From 4eaebdc06ea549c98b7477202d17db3a256bb219 Mon Sep 17 00:00:00 2001 From: Chili Date: Thu, 12 Mar 2026 17:03:16 +0900 Subject: [PATCH 01/42] draft 1 coordinator+provider namespace better logging draft 2 draft 3 draft 4 draft 5 draft 6 struct decom voiding draft 7 requestQpc lock --- AGENTS.md | 3 + IntelPresentMon/ControlLib/ControlLib.vcxproj | 10 +- .../ControlLib/ControlLib.vcxproj.filters | 7 +- .../ControlLib/TelemetryCoordinator.cpp | 527 ++++++++++++++++++ .../ControlLib/TelemetryCoordinator.h | 68 +++ .../ControlLib/TelemetryDeviceFingerprint.cpp | 78 +++ .../ControlLib/TelemetryDeviceFingerprint.h | 31 ++ .../ControlLib/TelemetryProvider.h | 30 + .../Interprocess/source/TelemetryMap.h | 1 + 9 files changed, 753 insertions(+), 2 deletions(-) create mode 100644 IntelPresentMon/ControlLib/TelemetryCoordinator.cpp create mode 100644 IntelPresentMon/ControlLib/TelemetryCoordinator.h create mode 100644 IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.cpp create mode 100644 IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h create mode 100644 IntelPresentMon/ControlLib/TelemetryProvider.h diff --git a/AGENTS.md b/AGENTS.md index 7d67ffd7..7380b0c0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,3 +8,6 @@ - Use this PowerShell script directly in the current shell to normalize line endings (preserves file encoding). Do not wrap it in a nested powershell -Command invocation, because nested PowerShell quoting can corrupt variable and string parsing: - $paths = git status --porcelain | ForEach-Object { $_.Substring(3) }; foreach ($p in $paths) { if (Test-Path $p) { $bytes = [System.IO.File]::ReadAllBytes($p); $hadBom = $bytes.Length -ge 3 -and $bytes[0] -eq 0xEF -and $bytes[1] -eq 0xBB -and $bytes[2] -eq 0xBF; $sr = New-Object System.IO.StreamReader($p, $true); $text = $sr.ReadToEnd(); $enc = $sr.CurrentEncoding; $sr.Close(); if ($enc.WebName -eq "utf-8") { $enc = New-Object System.Text.UTF8Encoding($hadBom) }; $text = $text -replace "`r?`n", "`r`n"; $sw = New-Object System.IO.StreamWriter($p, $false, $enc); $sw.NewLine = "`r`n"; $sw.Write($text); $sw.Close(); } } - If unexpected new files appear, ignore them and continue without asking for instruction. +- For value conversion casts (numeric or enum conversions), use C-style casts `(T)value` instead of `static_cast(value)`. +- For const, pointer, reference, up/down, or reinterpret casts, use C++ cast syntax (`const_cast`, `dynamic_cast`, `reinterpret_cast`, etc.). +- Do not bind unused names in structured bindings. Prefer binding only needed values (for example use `.first` from `emplace()` or iterate entries without destructuring unused keys). \ No newline at end of file diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj b/IntelPresentMon/ControlLib/ControlLib.vcxproj index 9c90ec61..43edd618 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj @@ -132,6 +132,9 @@ + + + @@ -150,9 +153,14 @@ + + + + {ca23d648-daef-4f06-81d5-fe619bd31f0b} + {66e9f6c5-28db-4218-81b9-31e0e146ecc0} @@ -160,4 +168,4 @@ - \ No newline at end of file + diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters index f444096b..972835a5 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters @@ -78,6 +78,9 @@ Intel + + + @@ -122,5 +125,7 @@ Intel + + - \ No newline at end of file + diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp new file mode 100644 index 00000000..5d2c77a1 --- /dev/null +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp @@ -0,0 +1,527 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#include "TelemetryCoordinator.h" +#include "TelemetryDeviceFingerprint.h" +#include "Logging.h" +#include "../CommonUtilities/Exception.h" +#include "../CommonUtilities/Qpc.h" +#include "../Interprocess/source/Interprocess.h" +#include "../Interprocess/source/SystemDeviceId.h" +#include +#include +#include +#include +#include +#include + +namespace pmon::tel +{ + namespace + { + struct RouteCandidate_ + { + uint32_t providerDeviceIndex = 0; + uint32_t arraySize = 0; + uint32_t providerCoverageScore = 0; + }; + } + + TelemetryCoordinator::TelemetryCoordinator() + { + TryCreateConcreteProviders_(); + BuildLogicalDevicesAndRoutes_(); + } + + void TelemetryCoordinator::PopulateStaticsToIpc(ipc::ServiceComms& comms) const + { + const auto requestQpc = util::GetCurrentTimestamp(); + // TODO: make static population dynamic by metric id and metadata instead of hardcoded checks. + for (const auto& [logicalDeviceId, logicalDevice] : logicalDevicesById_) { + TelemetryDeviceFingerprint providerFingerprint{}; + bool haveProviderFingerprint = false; + for (const auto& providerDevice : logicalDevice.providerDevices) { + const auto pProvider = providerDevice.pProvider.lock(); + if (!pProvider) { + pmlog_warn("Expired provider while resolving provider-device fingerprint for statics") + .pmwatch(logicalDevice.logicalDeviceId) + .pmwatch(providerDevice.providerDeviceId); + continue; + } + + try { + providerFingerprint = pProvider->GetFingerPrint(providerDevice.providerDeviceId); + haveProviderFingerprint = true; + break; + } + catch (...) { + pmlog_error(util::ReportException("Provider-device fingerprint query failed for statics")) + .pmwatch(logicalDevice.logicalDeviceId) + .pmwatch(providerDevice.providerDeviceId); + } + } + + try { + if (logicalDeviceId != ipc::kSystemDeviceId) { + auto& store = comms.GetGpuDataStore(logicalDevice.logicalDeviceId); + if (haveProviderFingerprint) { + store.statics.vendor = providerFingerprint.vendor; + store.statics.name = providerFingerprint.deviceName.c_str(); + } + else { + pmlog_warn("No provider-device fingerprint available for GPU static identity") + .pmwatch(logicalDevice.logicalDeviceId); + } + + if (logicalDevice.routes.contains(PM_METRIC_GPU_SUSTAINED_POWER_LIMIT)) { + const auto value = PollMetricForRoute_( + logicalDevice, PM_METRIC_GPU_SUSTAINED_POWER_LIMIT, 0, requestQpc); + if (const auto pVal = std::get_if(&value)) { + store.statics.sustainedPowerLimit = *pVal; + } + else { + throw util::Except<>("Type mismatch for PM_METRIC_GPU_SUSTAINED_POWER_LIMIT static metric"); + } + } + if (logicalDevice.routes.contains(PM_METRIC_GPU_MEM_SIZE)) { + const auto value = PollMetricForRoute_( + logicalDevice, PM_METRIC_GPU_MEM_SIZE, 0, requestQpc); + if (const auto pVal = std::get_if(&value)) { + store.statics.memSize = *pVal; + } + else { + throw util::Except<>("Type mismatch for PM_METRIC_GPU_MEM_SIZE static metric"); + } + } + if (logicalDevice.routes.contains(PM_METRIC_GPU_MEM_MAX_BANDWIDTH)) { + const auto value = PollMetricForRoute_( + logicalDevice, PM_METRIC_GPU_MEM_MAX_BANDWIDTH, 0, requestQpc); + if (const auto pVal = std::get_if(&value)) { + store.statics.maxMemBandwidth = *pVal; + } + else { + throw util::Except<>("Type mismatch for PM_METRIC_GPU_MEM_MAX_BANDWIDTH static metric"); + } + } + } + else { + auto& store = comms.GetSystemDataStore(); + if (haveProviderFingerprint) { + store.statics.cpuVendor = providerFingerprint.vendor; + store.statics.cpuName = providerFingerprint.deviceName.c_str(); + } + else { + pmlog_warn("No provider-device fingerprint available for system static identity") + .pmwatch(logicalDevice.logicalDeviceId); + } + + if (logicalDevice.routes.contains(PM_METRIC_CPU_POWER_LIMIT)) { + const auto value = PollMetricForRoute_( + logicalDevice, PM_METRIC_CPU_POWER_LIMIT, 0, requestQpc); + if (const auto pVal = std::get_if(&value)) { + store.statics.cpuPowerLimit = *pVal; + } + else { + throw util::Except<>("Type mismatch for PM_METRIC_CPU_POWER_LIMIT static metric"); + } + } + } + } + catch (...) { + pmlog_error(util::ReportException("PopulateStaticsToIpc failed for logical device")) + .pmwatch(logicalDevice.logicalDeviceId); + } + } + } + + ipc::MetricCapabilities TelemetryCoordinator::GetAvailability() const + { + ipc::MetricCapabilities availability; + + for (const auto& [logicalDeviceId, logicalDevice] : logicalDevicesById_) { + for (const auto& [metricId, providerDeviceIndex] : logicalDevice.routes) { + if (providerDeviceIndex >= logicalDevice.providerDevices.size()) { + pmlog_error("Route points outside provider device list in GetAvailability") + .pmwatch(logicalDeviceId) + .pmwatch((int)metricId) + .pmwatch(providerDeviceIndex) + .pmwatch(logicalDevice.providerDevices.size()); + continue; + } + + const auto& providerDevice = logicalDevice.providerDevices[providerDeviceIndex]; + const auto pProvider = providerDevice.pProvider.lock(); + if (!pProvider) { + pmlog_error("Route provider expired in GetAvailability") + .pmwatch(logicalDeviceId) + .pmwatch((int)metricId) + .pmwatch(providerDevice.providerDeviceId); + continue; + } + + TelemetryDeviceFingerprint providerFingerprint{}; + bool haveProviderFingerprint = false; + try { + providerFingerprint = pProvider->GetFingerPrint(providerDevice.providerDeviceId); + haveProviderFingerprint = true; + const auto capabilityMap = pProvider->GetCaps(); + const auto itDeviceCaps = capabilityMap.find(providerDevice.providerDeviceId); + if (itDeviceCaps == capabilityMap.end()) { + pmlog_error("Provider did not return caps for routed device in GetAvailability") + .pmwatch(logicalDeviceId) + .pmwatch((int)providerFingerprint.vendor) + .pmwatch(providerFingerprint.deviceName) + .pmwatch(providerDevice.providerDeviceId) + .pmwatch((int)metricId); + continue; + } + + const auto arraySize = itDeviceCaps->second.Check(metricId); + if (arraySize == 0) { + pmlog_error("Provider caps missing routed metric in GetAvailability") + .pmwatch(logicalDeviceId) + .pmwatch((int)providerFingerprint.vendor) + .pmwatch(providerFingerprint.deviceName) + .pmwatch(providerDevice.providerDeviceId) + .pmwatch((int)metricId); + continue; + } + + const auto existingSize = availability.Check(metricId); + if (arraySize > existingSize) { + availability.Set(metricId, arraySize); + } + } + catch (...) { + pmlog_error(util::ReportException("GetAvailability provider query failed")) + .pmwatch(logicalDeviceId) + .pmwatch((int)providerFingerprint.vendor) + .pmwatch(providerFingerprint.deviceName) + .pmwatch(haveProviderFingerprint) + .pmwatch(providerDevice.providerDeviceId) + .pmwatch((int)metricId); + } + } + } + + return availability; + } + + size_t TelemetryCoordinator::PollToIpc( + const std::span& metricUse, + ipc::ServiceComms& comms) const + { + const auto requestQpc = util::GetCurrentTimestamp(); + size_t samplesWritten = 0; + + for (const auto& use : metricUse) { + if (use.metric >= PM_METRIC_COUNT_) { + pmlog_warn("Invalid metric id in PollToIpc request") + .pmwatch((int)use.metric) + .pmwatch(use.deviceId) + .pmwatch(use.arrayIndex); + continue; + } + + const auto itLogical = logicalDevicesById_.find(use.deviceId); + if (itLogical == logicalDevicesById_.end()) { + pmlog_warn("Unknown logical device id in PollToIpc request") + .pmwatch(use.deviceId) + .pmwatch((int)use.metric) + .pmwatch(use.arrayIndex); + continue; + } + + const auto& logicalDevice = itLogical->second; + try { + const auto value = PollMetricForRoute_( + logicalDevice, use.metric, use.arrayIndex, requestQpc); + const auto qpc = (uint64_t)util::GetCurrentTimestamp(); + + if (logicalDevice.logicalDeviceId != ipc::kSystemDeviceId) { + auto& store = comms.GetGpuDataStore(logicalDevice.logicalDeviceId); + PushValueToTelemetryMap_(store.telemetryData, use.metric, use.arrayIndex, value, qpc); + } + else { + auto& store = comms.GetSystemDataStore(); + PushValueToTelemetryMap_(store.telemetryData, use.metric, use.arrayIndex, value, qpc); + } + + ++samplesWritten; + } + catch (...) { + pmlog_error(util::ReportException("PollToIpc failed while writing sample")) + .pmwatch(logicalDevice.logicalDeviceId) + .pmwatch((int)use.metric) + .pmwatch(use.arrayIndex); + } + } + + return samplesWritten; + } + + void TelemetryCoordinator::TryCreateConcreteProviders_() + { + // TODO: Add construction attempts for all concrete telemetry providers. + // TODO: Catch provider construction failures and continue with remaining providers. + } + + void TelemetryCoordinator::BuildLogicalDevicesAndRoutes_() + { + logicalDevicesById_.clear(); + nextLogicalDeviceId_ = 1; + + using CandidateMap = std::unordered_map>; + std::unordered_map routeCandidatesByLogicalId; + + for (const auto& pProvider : providerPtrs_) { + if (!pProvider) { + pmlog_error("Null pointer in provider ptrs"); + continue; + } + + try { + const auto capabilityMap = pProvider->GetCaps(); + for (const auto& [providerDeviceId, capabilities] : capabilityMap) { + const auto& fingerprint = pProvider->GetFingerPrint(providerDeviceId); + auto& logicalDevice = GetOrCreateLogicalDevice_(fingerprint); + const auto logicalDeviceId = logicalDevice.logicalDeviceId; + + uint32_t providerDeviceIndex = std::numeric_limits::max(); + for (uint32_t i = 0; i < logicalDevice.providerDevices.size(); ++i) { + const auto& existingProviderDevice = logicalDevice.providerDevices[i]; + if (existingProviderDevice.providerDeviceId != providerDeviceId) { + continue; + } + const auto pExisting = existingProviderDevice.pProvider.lock(); + if (pExisting.get() == pProvider.get()) { + providerDeviceIndex = i; + break; + } + } + + if (providerDeviceIndex == std::numeric_limits::max()) { + logicalDevice.providerDevices.push_back(ProviderDevice_{ pProvider, providerDeviceId }); + providerDeviceIndex = (uint32_t)(logicalDevice.providerDevices.size() - 1u); + } + + auto& metricCandidates = routeCandidatesByLogicalId[logicalDeviceId]; + for (const auto& [metricId, arraySize] : capabilities) { + if (metricId >= PM_METRIC_COUNT_ || arraySize == 0) { + pmlog_error("Invalid capability entry from provider") + .pmwatch((int)fingerprint.vendor) + .pmwatch(fingerprint.deviceName) + .pmwatch(providerDeviceId) + .pmwatch((int)metricId) + .pmwatch(arraySize); + continue; + } + + const auto clampedArraySize = (uint32_t)( + std::min(arraySize, size_t(std::numeric_limits::max()))); + metricCandidates[metricId].push_back(RouteCandidate_{ + providerDeviceIndex, + clampedArraySize, + 0 + }); + } + } + } + catch (...) { + pmlog_error(util::ReportException("BuildLogicalDevicesAndRoutes provider pass failed")); + continue; + } + } + + for (auto& [logicalDeviceId, metricCandidates] : routeCandidatesByLogicalId) { + const auto itLogical = logicalDevicesById_.find(logicalDeviceId); + if (itLogical == logicalDevicesById_.end()) { + pmlog_error("Missing logical device while finalizing routes") + .pmwatch(logicalDeviceId); + continue; + } + + auto& logicalDevice = itLogical->second; + std::unordered_map providerCoverage; + for (const auto& metricCandidatesEntry : metricCandidates) { + const auto& candidates = metricCandidatesEntry.second; + std::unordered_set countedProviderIndexes; + for (const auto& candidate : candidates) { + if (countedProviderIndexes.insert(candidate.providerDeviceIndex).second) { + ++providerCoverage[candidate.providerDeviceIndex]; + } + } + } + + for (auto& [metricId, candidates] : metricCandidates) { + for (auto& candidate : candidates) { + if (const auto itCoverage = providerCoverage.find(candidate.providerDeviceIndex); + itCoverage != providerCoverage.end()) { + candidate.providerCoverageScore = itCoverage->second; + } + } + + std::sort(candidates.begin(), candidates.end(), [](const RouteCandidate_& lhs, const RouteCandidate_& rhs) { + if (lhs.providerCoverageScore != rhs.providerCoverageScore) { + return lhs.providerCoverageScore > rhs.providerCoverageScore; + } + if (lhs.arraySize != rhs.arraySize) { + return lhs.arraySize > rhs.arraySize; + } + return lhs.providerDeviceIndex < rhs.providerDeviceIndex; + }); + + candidates.erase(std::unique(candidates.begin(), candidates.end(), + [](const RouteCandidate_& lhs, const RouteCandidate_& rhs) { + return lhs.providerDeviceIndex == rhs.providerDeviceIndex; + }), candidates.end()); + + if (candidates.empty()) { + pmlog_error("No route candidate available for metric") + .pmwatch(logicalDeviceId) + .pmwatch((int)metricId); + continue; + } + + const auto& selected = candidates.front(); + logicalDevice.routes[metricId] = selected.providerDeviceIndex; + } + } + + } + + TelemetryCoordinator::LogicalDevice_& TelemetryCoordinator::GetOrCreateLogicalDevice_( + const TelemetryDeviceFingerprint& fingerprint) + { + for (const auto& [logicalDeviceId, logicalDevice] : logicalDevicesById_) { + for (const auto& providerDevice : logicalDevice.providerDevices) { + const auto pProvider = providerDevice.pProvider.lock(); + if (!pProvider) { + pmlog_warn("Expired provider while matching logical devices") + .pmwatch(logicalDeviceId) + .pmwatch(providerDevice.providerDeviceId); + continue; + } + + try { + const auto& candidateFingerprint = pProvider->GetFingerPrint(providerDevice.providerDeviceId); + if (TelemetryDeviceFingerprintMatches(candidateFingerprint, fingerprint)) { + return logicalDevicesById_.at(logicalDeviceId); + } + } + catch (...) { + pmlog_error(util::ReportException("GetOrCreateLogicalDevice fingerprint query failed")) + .pmwatch(logicalDeviceId) + .pmwatch(providerDevice.providerDeviceId); + } + } + } + + uint32_t newId = 0; + if (fingerprint.deviceType == PM_DEVICE_TYPE_SYSTEM && + logicalDevicesById_.find(ipc::kSystemDeviceId) == logicalDevicesById_.end()) { + newId = ipc::kSystemDeviceId; + } + else { + while (true) { + if (nextLogicalDeviceId_ == ipc::kSystemDeviceId) { + ++nextLogicalDeviceId_; + } + newId = nextLogicalDeviceId_++; + if (logicalDevicesById_.find(newId) == logicalDevicesById_.end()) { + break; + } + } + } + + LogicalDevice_ logicalDevice{}; + logicalDevice.logicalDeviceId = newId; + auto itLogical = logicalDevicesById_.emplace(newId, std::move(logicalDevice)).first; + return itLogical->second; + } + + void TelemetryCoordinator::PushValueToTelemetryMap_( + ipc::TelemetryMap& telemetryMap, + PM_METRIC metricId, + uint32_t arrayIndex, + const TelemetryMetricValue& value, + uint64_t qpc) + { + try { + std::visit([&](const auto& sampleValue) -> void { + using ValueT = std::decay_t; + if (auto& rings = telemetryMap.FindRing(metricId); arrayIndex < rings.size()) { + if (!rings[arrayIndex].Push(sampleValue, qpc)) { + pmlog_error("Failed pushing telemetry sample to ring (backpressured timeout)") + .pmwatch((int)metricId) + .pmwatch(arrayIndex); + throw util::Except<>("Failed pushing telemetry sample to ring (backpressured timeout)"); + } + return; + } + else { + pmlog_error("Index out of bounds in telemetry ring") + .pmwatch((int)metricId) + .pmwatch(rings.size()) + .pmwatch(arrayIndex); + throw util::Except<>("Index out of bounds in telemetry ring"); + } + }, value); + } + catch (...) { + pmlog_error(util::ReportException("PushValueToTelemetryMap failed")) + .pmwatch((int)metricId) + .pmwatch(arrayIndex); + throw; + } + } + + TelemetryMetricValue TelemetryCoordinator::PollMetricForRoute_( + const LogicalDevice_& logicalDevice, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) const + { + const auto itRoute = logicalDevice.routes.find(metricId); + if (itRoute == logicalDevice.routes.end()) { + pmlog_error("No route found for metric on logical device") + .pmwatch(logicalDevice.logicalDeviceId) + .pmwatch((int)metricId) + .pmwatch(arrayIndex); + throw util::Except<>("No route found for metric on logical device"); + } + + const auto providerDeviceIndex = itRoute->second; + if (providerDeviceIndex >= logicalDevice.providerDevices.size()) { + pmlog_error("Route points outside provider device list") + .pmwatch(logicalDevice.logicalDeviceId) + .pmwatch((int)metricId) + .pmwatch(providerDeviceIndex) + .pmwatch(logicalDevice.providerDevices.size()); + throw util::Except<>("Route points outside provider device list"); + } + + const auto& providerDevice = logicalDevice.providerDevices[providerDeviceIndex]; + const auto pProvider = providerDevice.pProvider.lock(); + if (!pProvider) { + pmlog_error("Route provider expired") + .pmwatch(logicalDevice.logicalDeviceId) + .pmwatch((int)metricId) + .pmwatch(providerDevice.providerDeviceId) + .pmwatch(arrayIndex); + throw util::Except<>("Route provider expired"); + } + + try { + return pProvider->PollMetric(providerDevice.providerDeviceId, metricId, arrayIndex, requestQpc); + } + catch (...) { + pmlog_error(util::ReportException("PollMetricForRoute failed")) + .pmwatch(logicalDevice.logicalDeviceId) + .pmwatch(providerDevice.providerDeviceId) + .pmwatch((int)metricId) + .pmwatch(arrayIndex); + throw; + } + } + +} diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.h b/IntelPresentMon/ControlLib/TelemetryCoordinator.h new file mode 100644 index 00000000..e7da0bfc --- /dev/null +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.h @@ -0,0 +1,68 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#pragma once + +#include "TelemetryProvider.h" +#include +#include +#include +#include + +namespace pmon::ipc +{ + class ServiceComms; + class TelemetryMap; +} + +namespace pmon::tel +{ + class TelemetryCoordinator + { + public: + // Constructs all known concrete providers, correlates logical devices, + // and builds metric polling routes. + TelemetryCoordinator(); + // Populates available static data into IPC device stores. + void PopulateStaticsToIpc(ipc::ServiceComms& comms) const; + // Returns aggregate availability across all routed logical devices. + ipc::MetricCapabilities GetAvailability() const; + // Polls routed telemetry metrics and pushes samples directly to IPC rings. + size_t PollToIpc( + const std::span& metricUse, + ipc::ServiceComms& comms) const; + + private: + // types + struct ProviderDevice_ + { + std::weak_ptr pProvider; + uint32_t providerDeviceId; + }; + struct LogicalDevice_ + { + uint32_t logicalDeviceId = 0; + std::vector providerDevices; + // maps metrics to an index into providerDevices + std::unordered_map routes; + }; + // functions + void TryCreateConcreteProviders_(); + void BuildLogicalDevicesAndRoutes_(); + LogicalDevice_& GetOrCreateLogicalDevice_(const TelemetryDeviceFingerprint& fingerprint); + static void PushValueToTelemetryMap_( + ipc::TelemetryMap& telemetryMap, + PM_METRIC metricId, + uint32_t arrayIndex, + const TelemetryMetricValue& value, + uint64_t qpc); + TelemetryMetricValue PollMetricForRoute_( + const LogicalDevice_& logicalDevice, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) const; + // data + std::vector> providerPtrs_; + std::unordered_map logicalDevicesById_; + uint32_t nextLogicalDeviceId_ = 1; + }; +} diff --git a/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.cpp b/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.cpp new file mode 100644 index 00000000..a59f3950 --- /dev/null +++ b/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.cpp @@ -0,0 +1,78 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#include "TelemetryDeviceFingerprint.h" +#include + +namespace pmon::tel +{ + namespace + { + std::string NormalizeName_(const std::string& name) + { + std::string normalized; + normalized.reserve(name.size()); + for (const auto ch : name) { + const auto c = static_cast(ch); + if (std::isalnum(c)) { + normalized.push_back(static_cast(std::tolower(c))); + } + } + return normalized; + } + + template + bool OptionalEqual_(const std::optional& lhs, const std::optional& rhs) noexcept + { + return lhs.has_value() && rhs.has_value() && (*lhs == *rhs); + } + } + + bool TelemetryDeviceFingerprintMatches( + const TelemetryDeviceFingerprint& lhs, + const TelemetryDeviceFingerprint& rhs) noexcept + { + if (lhs.deviceType != rhs.deviceType || lhs.vendor != rhs.vendor) { + return false; + } + + if (OptionalEqual_(lhs.pciDeviceId, rhs.pciDeviceId) && + OptionalEqual_(lhs.pciSubSystemId, rhs.pciSubSystemId)) { + return true; + } + + if (OptionalEqual_(lhs.pciBusId, rhs.pciBusId)) { + return true; + } + + if (!lhs.deviceName.empty() && !rhs.deviceName.empty()) { + return NormalizeName_(lhs.deviceName) == NormalizeName_(rhs.deviceName); + } + + return false; + } + + void MergeTelemetryDeviceFingerprint( + TelemetryDeviceFingerprint& dst, + const TelemetryDeviceFingerprint& src) + { + if (dst.vendor == PM_DEVICE_VENDOR_UNKNOWN && src.vendor != PM_DEVICE_VENDOR_UNKNOWN) { + dst.vendor = src.vendor; + } + + if (dst.deviceName.empty() && !src.deviceName.empty()) { + dst.deviceName = src.deviceName; + } + + if (!dst.pciDeviceId.has_value() && src.pciDeviceId.has_value()) { + dst.pciDeviceId = src.pciDeviceId; + } + + if (!dst.pciSubSystemId.has_value() && src.pciSubSystemId.has_value()) { + dst.pciSubSystemId = src.pciSubSystemId; + } + + if (!dst.pciBusId.has_value() && src.pciBusId.has_value()) { + dst.pciBusId = src.pciBusId; + } + } +} diff --git a/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h b/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h new file mode 100644 index 00000000..d6ec6a9d --- /dev/null +++ b/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h @@ -0,0 +1,31 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#pragma once + +#include "../PresentMonAPI2/PresentMonAPI.h" +#include +#include +#include + +namespace pmon::tel +{ + struct TelemetryDeviceFingerprint + { + PM_DEVICE_TYPE deviceType = PM_DEVICE_TYPE_INDEPENDENT; + PM_DEVICE_VENDOR vendor = PM_DEVICE_VENDOR_UNKNOWN; + std::string deviceName; + + // Correlation fields aligned with NVIDIA legacy matching. + std::optional pciDeviceId; + std::optional pciSubSystemId; + std::optional pciBusId; + }; + + bool TelemetryDeviceFingerprintMatches( + const TelemetryDeviceFingerprint& lhs, + const TelemetryDeviceFingerprint& rhs) noexcept; + + void MergeTelemetryDeviceFingerprint( + TelemetryDeviceFingerprint& dst, + const TelemetryDeviceFingerprint& src); +} diff --git a/IntelPresentMon/ControlLib/TelemetryProvider.h b/IntelPresentMon/ControlLib/TelemetryProvider.h new file mode 100644 index 00000000..1d2e9310 --- /dev/null +++ b/IntelPresentMon/ControlLib/TelemetryProvider.h @@ -0,0 +1,30 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#pragma once + +#include "TelemetryDeviceFingerprint.h" +#include "../Interprocess/source/MetricCapabilities.h" +#include "../Interprocess/source/TelemetryMap.h" +#include +#include +#include + +namespace pmon::tel +{ + using ProviderDeviceId = uint32_t; + using ProviderCapabilityMap = std::unordered_map; + using TelemetryMetricValue = ipc::TelemetryMap::ScalarValueType; + + class TelemetryProvider + { + public: + virtual ~TelemetryProvider() = default; + virtual ProviderCapabilityMap GetCaps() = 0; + virtual const TelemetryDeviceFingerprint& GetFingerPrint(ProviderDeviceId providerDeviceId) const = 0; + virtual TelemetryMetricValue PollMetric( + ProviderDeviceId providerDeviceId, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) = 0; + }; +} diff --git a/IntelPresentMon/Interprocess/source/TelemetryMap.h b/IntelPresentMon/Interprocess/source/TelemetryMap.h index 668c9b38..ee11ef84 100644 --- a/IntelPresentMon/Interprocess/source/TelemetryMap.h +++ b/IntelPresentMon/Interprocess/source/TelemetryMap.h @@ -10,6 +10,7 @@ namespace pmon::ipc class TelemetryMap { public: + using ScalarValueType = std::variant; template using HistoryRingVect = ShmVector>; using MapValueType = std::variant< From 33a4360cfeb8267967e698932ad908c4d10cba75 Mon Sep 17 00:00:00 2001 From: Chili Date: Fri, 13 Mar 2026 16:40:58 +0900 Subject: [PATCH 02/42] device metric use mapping --- AGENTS.md | 3 +- .../InterimBroadcasterTests.cpp | 4 +- .../PresentMonMiddleware/Middleware.cpp | 4 +- .../ActionExecutionContext.cpp | 12 +-- .../ActionExecutionContext.h | 47 +----------- IntelPresentMon/PresentMonService/MetricUse.h | 54 ++++++++++++++ .../PresentMonService/PMMainThread.cpp | 21 +++--- .../PresentMonService/PresentMon.h | 73 +++++++++++++++---- .../PresentMonService.vcxproj | 1 + .../PresentMonService.vcxproj.filters | 1 + 10 files changed, 136 insertions(+), 84 deletions(-) create mode 100644 IntelPresentMon/PresentMonService/MetricUse.h diff --git a/AGENTS.md b/AGENTS.md index 7380b0c0..1a84031c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,4 +10,5 @@ - If unexpected new files appear, ignore them and continue without asking for instruction. - For value conversion casts (numeric or enum conversions), use C-style casts `(T)value` instead of `static_cast(value)`. - For const, pointer, reference, up/down, or reinterpret casts, use C++ cast syntax (`const_cast`, `dynamic_cast`, `reinterpret_cast`, etc.). -- Do not bind unused names in structured bindings. Prefer binding only needed values (for example use `.first` from `emplace()` or iterate entries without destructuring unused keys). \ No newline at end of file +- Do not bind unused names in structured bindings. Prefer binding only needed values (for example use `.first` from `emplace()` or iterate entries without destructuring unused keys). +- Do not fully qualify namespaces when not needed by local scope (for example prefer `MetricUse` or `svc::MetricUse` over `pmon::svc::MetricUse` when already inside `pmon::svc::acts` or with suitable using scope). \ No newline at end of file diff --git a/IntelPresentMon/PresentMonAPI2Tests/InterimBroadcasterTests.cpp b/IntelPresentMon/PresentMonAPI2Tests/InterimBroadcasterTests.cpp index bacf3442..1fe94314 100644 --- a/IntelPresentMon/PresentMonAPI2Tests/InterimBroadcasterTests.cpp +++ b/IntelPresentMon/PresentMonAPI2Tests/InterimBroadcasterTests.cpp @@ -416,7 +416,7 @@ namespace InterimBroadcasterTests { // build metric use set from above store results - std::unordered_set uses; + std::unordered_set uses; for (auto&& [met, siz] : storeRings) { if (siz > 0) { uses.insert({ met, ipc::kSystemDeviceId, 0 }); @@ -671,7 +671,7 @@ namespace InterimBroadcasterTests { // build metric use set from above introspection results - std::unordered_set uses; + std::unordered_set uses; for (auto&& [met, siz] : introspectionAvailability) { if (siz > 0) { uses.insert({ met, TargetDeviceID, 0 }); diff --git a/IntelPresentMon/PresentMonMiddleware/Middleware.cpp b/IntelPresentMon/PresentMonMiddleware/Middleware.cpp index c19660b8..5601f3f3 100644 --- a/IntelPresentMon/PresentMonMiddleware/Middleware.cpp +++ b/IntelPresentMon/PresentMonMiddleware/Middleware.cpp @@ -416,12 +416,12 @@ namespace pmon::mid void Middleware::UpdateMetricUsage_() { - std::unordered_set usage; + std::unordered_set usage; // TODO: remove intro here as it is not necessary const auto& introRoot = GetIntrospectionRoot_(); for (const auto& [handle, elements] : queryMetricUsage_) { for (const auto& element : elements) { - usage.insert(svc::acts::MetricUse{ + usage.insert(svc::MetricUse{ .metricId = element.metric, .deviceId = element.deviceId, .arrayIdx = element.arrayIndex, diff --git a/IntelPresentMon/PresentMonService/ActionExecutionContext.cpp b/IntelPresentMon/PresentMonService/ActionExecutionContext.cpp index c87450cd..9b82758c 100644 --- a/IntelPresentMon/PresentMonService/ActionExecutionContext.cpp +++ b/IntelPresentMon/PresentMonService/ActionExecutionContext.cpp @@ -63,21 +63,13 @@ namespace pmon::svc::acts } void ActionExecutionContext::UpdateMetricUsage() const { - std::unordered_set aggregateMetricUsage; - std::unordered_set deviceMetricUsage; + auto deviceMetricUsage = std::make_shared(); auto&& allUsageSets = util::rng::MemberSlice(*pSessionMap, &SessionContextType::metricUsage); for (auto&& clientUsageSet : allUsageSets) { for (auto&& usage : clientUsageSet) { - aggregateMetricUsage.insert(usage); - deviceMetricUsage.insert(usage.deviceId); + (*deviceMetricUsage)[usage.deviceId].insert(usage); } } - if (!hasLastAggregateMetricUsage || aggregateMetricUsage != lastAggregateMetricUsage) { - pmlog_verb(pmon::util::log::V::met_use)("Aggregate metric usage updated") - .serialize("aggregateMetricUsage", aggregateMetricUsage); - lastAggregateMetricUsage = aggregateMetricUsage; - hasLastAggregateMetricUsage = true; - } pPmon->SetDeviceMetricUsage(std::move(deviceMetricUsage)); } diff --git a/IntelPresentMon/PresentMonService/ActionExecutionContext.h b/IntelPresentMon/PresentMonService/ActionExecutionContext.h index fa121edf..b0fd405d 100644 --- a/IntelPresentMon/PresentMonService/ActionExecutionContext.h +++ b/IntelPresentMon/PresentMonService/ActionExecutionContext.h @@ -1,7 +1,6 @@ #pragma once #include "../Interprocess/source/act/SymmetricActionConnector.h" #include "../Interprocess/source/ShmNamer.h" -#include "../CommonUtilities/Hash.h" #include "../CommonUtilities/win/Handle.h" #include #include @@ -13,58 +12,16 @@ #include #include #include -#include #include #include "PresentMon.h" #include "Service.h" #include "FrameBroadcaster.h" +#include "MetricUse.h" namespace pmon::svc::acts { struct ActionExecutionContext; - // TODO: move this struct into its own header - struct MetricUse - { - PM_METRIC metricId; - uint32_t deviceId; - uint32_t arrayIdx; - - template - void serialize(A& ar) - { - ar(CEREAL_NVP(metricId), - CEREAL_NVP(deviceId), - CEREAL_NVP(arrayIdx)); - } - - bool operator==(const MetricUse& rhs) const - { - return metricId == rhs.metricId && - deviceId == rhs.deviceId && - arrayIdx == rhs.arrayIdx; - } - }; -} - -// Must be visible before any std::unordered_set instantiation -namespace std -{ - template<> - struct hash - { - size_t operator()(const pmon::svc::acts::MetricUse& mu) const noexcept - { - const uint64_t devIdx = - (uint64_t(mu.deviceId) << 32) | uint64_t(mu.arrayIdx); - - // Avoid depending on std::hash existing: - using Under = std::underlying_type_t; - const Under mid = static_cast(mu.metricId); - - return pmon::util::hash::DualHash(mid, devIdx); - } - }; } namespace pmon::svc::acts @@ -103,8 +60,6 @@ namespace pmon::svc::acts PresentMon* pPmon = nullptr; const std::unordered_map* pSessionMap = nullptr; std::optional responseWriteTimeoutMs; - mutable std::unordered_set lastAggregateMetricUsage; - mutable bool hasLastAggregateMetricUsage = false; // functions void Dispose(SessionContextType& stx); diff --git a/IntelPresentMon/PresentMonService/MetricUse.h b/IntelPresentMon/PresentMonService/MetricUse.h new file mode 100644 index 00000000..ac4ef4b0 --- /dev/null +++ b/IntelPresentMon/PresentMonService/MetricUse.h @@ -0,0 +1,54 @@ +#pragma once +#include "../CommonUtilities/Hash.h" +#include +#include +#include +#include +#include + +namespace pmon::svc +{ + struct MetricUse + { + PM_METRIC metricId; + uint32_t deviceId; + uint32_t arrayIdx; + + template + void serialize(A& ar) + { + ar(CEREAL_NVP(metricId), + CEREAL_NVP(deviceId), + CEREAL_NVP(arrayIdx)); + } + + bool operator==(const MetricUse& rhs) const + { + return metricId == rhs.metricId && + deviceId == rhs.deviceId && + arrayIdx == rhs.arrayIdx; + } + }; + + using DeviceMetricUse = std::unordered_map>; +} + +// Must be visible before any std::unordered_set instantiation +namespace std +{ + template<> + struct hash + { + size_t operator()(const pmon::svc::MetricUse& mu) const noexcept + { + const uint64_t devIdx = + (uint64_t(mu.deviceId) << 32) | uint64_t(mu.arrayIdx); + + // Avoid depending on std::hash existing: + using Under = std::underlying_type_t; + const Under mid = (Under)mu.metricId; + + return pmon::util::hash::DualHash(mid, devIdx); + } + }; +} diff --git a/IntelPresentMon/PresentMonService/PMMainThread.cpp b/IntelPresentMon/PresentMonService/PMMainThread.cpp index a51d8f0b..cd39b8b8 100644 --- a/IntelPresentMon/PresentMonService/PMMainThread.cpp +++ b/IntelPresentMon/PresentMonService/PMMainThread.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Intel Corporation +// Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: MIT #include "Logging.h" #include "Service.h" @@ -435,10 +435,11 @@ void PowerTelemetryThreadEntry_(Service* const srv, PresentMon* const pm, } else { // if any of our gpu telemetry devices are active enter polling loop + const auto deviceUsage = pm->GetDeviceMetricUsageSnapshot(); bool hasActive = false; for (auto&& adapter : ptc->GetPowerTelemetryAdapters()) { const auto deviceId = adapter->GetDeviceId(); - if (pm->CheckDeviceMetricUsage(deviceId)) { + if (deviceUsage->contains(deviceId)) { pmlog_dbg("detected gpu active").pmwatch(deviceId); hasActive = true; break; @@ -460,9 +461,10 @@ void PowerTelemetryThreadEntry_(Service* const srv, PresentMon* const pm, } // poll all gpu adapter devices, skipping inactive devices auto& adapters = ptc->GetPowerTelemetryAdapters(); + const auto deviceUsage = pm->GetDeviceMetricUsageSnapshot(); for (auto&& adapter : adapters) { const auto deviceId = adapter->GetDeviceId(); - if (!pm->CheckDeviceMetricUsage(deviceId)) { + if (!deviceUsage->contains(deviceId)) { continue; } // Get the newest sample from the provider @@ -480,7 +482,7 @@ void PowerTelemetryThreadEntry_(Service* const srv, PresentMon* const pm, // conditions for ending active poll and returning to idle state // go dormant if no gpu devices are in use const bool anyUsed = std::ranges::any_of(adapters, - [&](const auto& adapter) { return pm->CheckDeviceMetricUsage(adapter->GetDeviceId()); }); + [&](const auto& adapter) { return deviceUsage->contains(adapter->GetDeviceId()); }); if (!anyUsed) { break; } @@ -520,7 +522,8 @@ void CpuTelemetryThreadEntry_(Service* const srv, PresentMon* const pm, ipc::Ser } else { // if system telemetry metrics active enter active polling loop - if (pm->CheckDeviceMetricUsage(ipc::kSystemDeviceId)) { + const auto deviceUsage = pm->GetDeviceMetricUsageSnapshot(); + if (deviceUsage->contains(ipc::kSystemDeviceId)) { pmlog_dbg("detected system active"); } else { @@ -529,6 +532,10 @@ void CpuTelemetryThreadEntry_(Service* const srv, PresentMon* const pm, ipc::Ser } } while (!WaitAnyEventFor(0ms, srv->GetServiceStopHandle())) { + const auto deviceUsage = pm->GetDeviceMetricUsageSnapshot(); + if (!deviceUsage->contains(ipc::kSystemDeviceId)) { + break; + } // TODO:streamer replace this flow with a call that populates rings of a store // placeholder routine shim to translate cpu tranfer struct into rings // replace with a direct mapping on PM_METRIC that obviates the switch @@ -562,10 +569,6 @@ void CpuTelemetryThreadEntry_(Service* const srv, PresentMon* const pm, ipc::Ser // ms and SetInterval expects seconds. waiter.SetInterval(pm->GetGpuTelemetryPeriod() / 1000.); waiter.Wait(); - // conditions for ending active poll and returning to idle state - if (!pm->CheckDeviceMetricUsage(ipc::kSystemDeviceId)) { - break; - } } } } diff --git a/IntelPresentMon/PresentMonService/PresentMon.h b/IntelPresentMon/PresentMonService/PresentMon.h index fbe3a2f6..b5e77341 100644 --- a/IntelPresentMon/PresentMonService/PresentMon.h +++ b/IntelPresentMon/PresentMonService/PresentMon.h @@ -4,8 +4,8 @@ #include "PresentMonSession.h" #include "EtwLogger.h" #include "FrameBroadcaster.h" +#include "MetricUse.h" #include "../CommonUtilities/win/Event.h" -#include "../CommonUtilities/Hash.h" #include #include #include @@ -14,12 +14,16 @@ #include #include #include +#include +#include using namespace pmon; class PresentMon { public: + using DeviceMetricUsage = svc::DeviceMetricUse; + PresentMon(svc::FrameBroadcaster& broadcaster, bool isRealtime); ~PresentMon(); @@ -93,21 +97,61 @@ class PresentMon { return !isRealtime_; } - bool CheckDeviceMetricUsage(uint32_t deviceId) const + bool CheckDeviceMetricUsage(std::optional deviceId, + std::optional metricId = std::nullopt, + std::optional arrayIdx = std::nullopt) const + { + const auto usageData = metricDeviceUsage_.load(std::memory_order_acquire); + if (!usageData) { + return false; + } + + const auto selectionMatches = [&](const std::unordered_set& selection) -> bool { + if (!metricId) { + // array index without metric is not a valid query form + if (arrayIdx) { + return false; + } + return !selection.empty(); + } + for (const auto& metricUse : selection) { + if (metricUse.metricId != *metricId) { + continue; + } + if (!arrayIdx || metricUse.arrayIdx == *arrayIdx) { + return true; + } + } + return false; + }; + + if (deviceId) { + if (auto it = usageData->find(*deviceId); it != usageData->end()) { + return selectionMatches(it->second); + } + return false; + } + + for (const auto& usageEntry : *usageData) { + if (selectionMatches(usageEntry.second)) { + return true; + } + } + return false; + } + std::shared_ptr GetDeviceMetricUsageSnapshot() const { - std::shared_lock lk{ metricDeviceUsageMtx_ }; - return metricDeviceUsage_.contains(deviceId); + return metricDeviceUsage_.load(std::memory_order_acquire); } - void SetDeviceMetricUsage(std::unordered_set usage) + void SetDeviceMetricUsage(std::shared_ptr usage) { - // we need exclusive lock to prevent concurrent access to usage data while being modified - { - std::lock_guard lk{ metricDeviceUsageMtx_ }; - metricDeviceUsage_ = std::move(usage); + if (!usage) { + usage = std::make_shared(); } + metricDeviceUsage_.store(std::move(usage), std::memory_order_release); // keep shared lock now to prevent modification to event set while we are iterating it // if this were non-shared, it would cause the listeners to block immediately on wake - std::shared_lock lk2{ metricDeviceUsageMtx_ }; + std::shared_lock lk2{ deviceUsageEvtMtx_ }; for (auto& kv : deviceUsageEvts_) { kv.second.Set(); } @@ -116,13 +160,13 @@ class PresentMon { const DeviceUsageEvtKey key{ loc.file_name(), (uint32_t)loc.line() }; { - std::shared_lock lk{ metricDeviceUsageMtx_ }; + std::shared_lock lk{ deviceUsageEvtMtx_ }; if (auto it = deviceUsageEvts_.find(key); it != deviceUsageEvts_.end()) { return it->second.Get(); } } // get non-shared lock for modification purposes (add new event) - std::lock_guard lk2{ metricDeviceUsageMtx_ }; + std::lock_guard lk2{ deviceUsageEvtMtx_ }; auto it = deviceUsageEvts_.emplace(key, util::win::Event{ false, false }).first; return it->second.Get(); } @@ -133,8 +177,9 @@ class PresentMon svc::EtwLogger etwLogger_; std::unique_ptr pSession_; bool isRealtime_ = true; - mutable std::shared_mutex metricDeviceUsageMtx_; - std::unordered_set metricDeviceUsage_; + std::atomic> metricDeviceUsage_{ + std::make_shared() }; + mutable std::shared_mutex deviceUsageEvtMtx_; using DeviceUsageEvtKey = std::pair; mutable std::unordered_map deviceUsageEvts_; }; diff --git a/IntelPresentMon/PresentMonService/PresentMonService.vcxproj b/IntelPresentMon/PresentMonService/PresentMonService.vcxproj index 0df6be30..9121f5d8 100644 --- a/IntelPresentMon/PresentMonService/PresentMonService.vcxproj +++ b/IntelPresentMon/PresentMonService/PresentMonService.vcxproj @@ -153,6 +153,7 @@ + diff --git a/IntelPresentMon/PresentMonService/PresentMonService.vcxproj.filters b/IntelPresentMon/PresentMonService/PresentMonService.vcxproj.filters index 4b3cbc4a..efe8e1c7 100644 --- a/IntelPresentMon/PresentMonService/PresentMonService.vcxproj.filters +++ b/IntelPresentMon/PresentMonService/PresentMonService.vcxproj.filters @@ -31,6 +31,7 @@ + From bf1928a758fe86481fd6cc59f856971e9f2e775b Mon Sep 17 00:00:00 2001 From: Chili Date: Sat, 14 Mar 2026 06:58:15 +0900 Subject: [PATCH 03/42] making igcl --- IntelPresentMon/ControlLib/ControlLib.vcxproj | 15 +- .../ControlLib/ControlLib.vcxproj.filters | 19 +- ...ider.cpp => IgclErrorCodeProvider_old.cpp} | 2 +- ...cpp => IntelPowerTelemetryAdapter_old.cpp} | 0 ...pp => IntelPowerTelemetryProvider_old.cpp} | 0 IntelPresentMon/ControlLib/TelemetryCache.h | 32 + .../ControlLib/cApiWrapper_old.cpp | 5784 +++++++++++ .../ControlLib/igcl/IgclErrorCodeProvider.cpp | 21 + .../ControlLib/igcl/IgclErrorCodeProvider.h | 12 + .../ControlLib/igcl/IgclTelemetryProvider.cpp | 927 ++ .../ControlLib/igcl/IgclTelemetryProvider.h | 113 + .../ControlLib/{ => igcl}/cApiWrapper.cpp | 2 +- IntelPresentMon/ControlLib/igcl/igcl_api.h | 8976 +++++++++++++++++ 13 files changed, 15893 insertions(+), 10 deletions(-) rename IntelPresentMon/ControlLib/{IgclErrorCodeProvider.cpp => IgclErrorCodeProvider_old.cpp} (93%) rename IntelPresentMon/ControlLib/{IntelPowerTelemetryAdapter.cpp => IntelPowerTelemetryAdapter_old.cpp} (100%) rename IntelPresentMon/ControlLib/{IntelPowerTelemetryProvider.cpp => IntelPowerTelemetryProvider_old.cpp} (100%) create mode 100644 IntelPresentMon/ControlLib/TelemetryCache.h create mode 100644 IntelPresentMon/ControlLib/cApiWrapper_old.cpp create mode 100644 IntelPresentMon/ControlLib/igcl/IgclErrorCodeProvider.cpp create mode 100644 IntelPresentMon/ControlLib/igcl/IgclErrorCodeProvider.h create mode 100644 IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp create mode 100644 IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.h rename IntelPresentMon/ControlLib/{ => igcl}/cApiWrapper.cpp (99%) create mode 100644 IntelPresentMon/ControlLib/igcl/igcl_api.h diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj b/IntelPresentMon/ControlLib/ControlLib.vcxproj index 43edd618..7188846d 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj @@ -115,6 +115,8 @@ + + @@ -128,6 +130,8 @@ + + @@ -140,10 +144,13 @@ - - - - + + + + + + + diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters index 972835a5..76c2a630 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters @@ -81,6 +81,12 @@ + + + Intel + + + @@ -98,13 +104,13 @@ Nvidia - + Intel - + Intel - + Intel @@ -122,10 +128,15 @@ - + + Intel + + Intel + + diff --git a/IntelPresentMon/ControlLib/IgclErrorCodeProvider.cpp b/IntelPresentMon/ControlLib/IgclErrorCodeProvider_old.cpp similarity index 93% rename from IntelPresentMon/ControlLib/IgclErrorCodeProvider.cpp rename to IntelPresentMon/ControlLib/IgclErrorCodeProvider_old.cpp index f4045345..bc27b09d 100644 --- a/IntelPresentMon/ControlLib/IgclErrorCodeProvider.cpp +++ b/IntelPresentMon/ControlLib/IgclErrorCodeProvider_old.cpp @@ -1,4 +1,4 @@ -#include "IgclErrorCodeProvider.h" +#include "IgclErrorCodeProvider.h" #include "../CommonUtilities/log/ErrorCode.h" #include "../CommonUtilities/ref/GeneratedReflection.h" #include "igcl_api.h" diff --git a/IntelPresentMon/ControlLib/IntelPowerTelemetryAdapter.cpp b/IntelPresentMon/ControlLib/IntelPowerTelemetryAdapter_old.cpp similarity index 100% rename from IntelPresentMon/ControlLib/IntelPowerTelemetryAdapter.cpp rename to IntelPresentMon/ControlLib/IntelPowerTelemetryAdapter_old.cpp diff --git a/IntelPresentMon/ControlLib/IntelPowerTelemetryProvider.cpp b/IntelPresentMon/ControlLib/IntelPowerTelemetryProvider_old.cpp similarity index 100% rename from IntelPresentMon/ControlLib/IntelPowerTelemetryProvider.cpp rename to IntelPresentMon/ControlLib/IntelPowerTelemetryProvider_old.cpp diff --git a/IntelPresentMon/ControlLib/TelemetryCache.h b/IntelPresentMon/ControlLib/TelemetryCache.h new file mode 100644 index 00000000..7ec0cb16 --- /dev/null +++ b/IntelPresentMon/ControlLib/TelemetryCache.h @@ -0,0 +1,32 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#pragma once + +#include + +namespace pmon::tele +{ + template + struct EndpointCache + { + T output{}; + int64_t requestQpc = 0; + + bool HasValue(int64_t candidateRequestQpc) const noexcept + { + return requestQpc != 0 && candidateRequestQpc != 0 && + requestQpc == candidateRequestQpc; + } + + void Store(int64_t newRequestQpc, const T& newOutput) noexcept + { + output = newOutput; + requestQpc = newRequestQpc; + } + + void Clear() noexcept + { + requestQpc = 0; + } + }; +} diff --git a/IntelPresentMon/ControlLib/cApiWrapper_old.cpp b/IntelPresentMon/ControlLib/cApiWrapper_old.cpp new file mode 100644 index 00000000..8bd953c9 --- /dev/null +++ b/IntelPresentMon/ControlLib/cApiWrapper_old.cpp @@ -0,0 +1,5784 @@ +//=========================================================================== +//Copyright (C) 2025 Intel Corporation +// +// +// +//SPDX-License-Identifier: MIT +//-------------------------------------------------------------------------- + +/** + * + * @file ctl_api.cpp + * @version v1-r1 + * + */ + +// Note: UWP applications should have defined WINDOWS_UWP in their compiler settings +// Also at this point, it's easier by not enabling pre-compiled option to compile this file +// Not all functionalities are tested for a UWP application + +#include +#include +#include + +//#define CTL_APIEXPORT + +#include "igcl_api.h" + +///////////////////////////////////////////////////////////////////////////////// +// +// Implementation of wrapper functions +// +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 + #define CTL_DLL_NAME L"ControlLib32" +#endif +#define CTL_DLL_PATH_LEN 512 + +ctl_result_t GetControlAPIDLLPath(ctl_init_args_t* pInitArgs, wchar_t* pwcDLLPath) +{ + if ((NULL == pRuntimeArgs) || (NULL == pRuntimeArgs->pRuntimePath)) + { + // Load the requested DLL based on major version in init args + uint16_t majorVersion = CTL_MAJOR_VERSION(pInitArgs->AppVersion); + + // If caller's major version is higher than the DLL's, then simply not support the caller! + // This is not supposed to happen as wrapper is part of the app itself which includes igcl_api.h with right major version + 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) + { + // caller specified a specific RT, use it instead + wcsncpy_s(pwcDLLPath, CTL_DLL_PATH_LEN, pRuntimeArgs->pRuntimePath, CTL_DLL_PATH_LEN - 1); + } + return CTL_RESULT_SUCCESS; +} + + + +/** +* @brief Control Api Init +* +* @details +* - Control Api Init +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pInitDesc` +* + `nullptr == phAPIHandle` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlInit( + ctl_init_args_t* pInitDesc, ///< [in][out] App's control API version + ctl_api_handle_t* phAPIHandle ///< [in][out][release] Control API handle + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + // special code - only for ctlInit() + if (NULL == hinstLib) + { + 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.data(), 0); +#else + DWORD dwFlags = LOAD_LIBRARY_SEARCH_SYSTEM32; +#ifdef _DEBUG + dwFlags = dwFlags | LOAD_LIBRARY_SEARCH_APPLICATION_DIR; +#endif + hinstLib = LoadLibraryExW(strDLLPath.data(), NULL, dwFlags); +#endif + if (NULL == hinstLib) + { + result = CTL_RESULT_ERROR_LOAD; + } + else if (pRuntimeArgs) + { + ctlSetRuntimePath(pRuntimeArgs); + } + } + } + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnInit_t pfnInit = (ctl_pfnInit_t)GetProcAddress(hinstLibPtr, "ctlInit"); + if (pfnInit) + { + result = pfnInit(pInitDesc, phAPIHandle); + } + } + + return result; +} + + +/** +* @brief Control Api Destroy +* +* @details +* - Control Api Close +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hAPIHandle` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlClose( + ctl_api_handle_t hAPIHandle ///< [in][release] Control API implementation handle obtained during init + ///< call + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnClose_t pfnClose = (ctl_pfnClose_t)GetProcAddress(hinstLibPtr, "ctlClose"); + if (pfnClose) + { + result = pfnClose(hAPIHandle); + } + } + + // 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 + if( result == CTL_RESULT_SUCCESS) + { + if (NULL != hinstLib) + { + FreeLibrary(hinstLib); + hinstLib = NULL; + } + } + // set runtime args back to NULL + // no need to free this as it's allocated by caller + pRuntimeArgs = NULL; + return result; +} + + +/** +* @brief Runtime path +* +* @details +* - Control Api set runtime path. Optional call from a loader which allows +* the loaded runtime to enumerate only the adapters which the specified +* runtime is responsible for. This is done usually by a loader or by +* callers who know how to get the specific runtime of interest. This +* call right now is reserved for use by Intel components. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pArgs` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlSetRuntimePath( + ctl_runtime_path_args_t* pArgs ///< [in] Runtime path + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnSetRuntimePath_t pfnSetRuntimePath = (ctl_pfnSetRuntimePath_t)GetProcAddress(hinstLibPtr, "ctlSetRuntimePath"); + if (pfnSetRuntimePath) + { + result = pfnSetRuntimePath(pArgs); + } + } + + // 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 + 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 + pRuntimeArgs = pArgs; + result = CTL_RESULT_SUCCESS; + } + return result; +} + + +/** +* @brief Wait for a property change. Note that this is a blocking call +* +* @details +* - Wait for a property change in display, 3d, media etc. +* +* @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 == pArgs` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlWaitForPropertyChange( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter + ctl_wait_property_change_args_t* pArgs ///< [in] Argument containing information about which property changes to + ///< listen for + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnWaitForPropertyChange_t pfnWaitForPropertyChange = (ctl_pfnWaitForPropertyChange_t)GetProcAddress(hinstLibPtr, "ctlWaitForPropertyChange"); + if (pfnWaitForPropertyChange) + { + result = pfnWaitForPropertyChange(hDeviceAdapter, pArgs); + } + } + + return result; +} + + +/** +* @brief Reserved function +* +* @details +* - Reserved function +* +* @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 == pArgs` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlReservedCall( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter + ctl_reserved_args_t* pArgs ///< [in] Argument containing information + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnReservedCall_t pfnReservedCall = (ctl_pfnReservedCall_t)GetProcAddress(hinstLibPtr, "ctlReservedCall"); + if (pfnReservedCall) + { + result = pfnReservedCall(hDeviceAdapter, pArgs); + } + } + + return result; +} + + +/** +* @brief Get 3D capabilities +* +* @details +* - The application gets 3D 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 +ctlGetSupported3DCapabilities( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + ctl_3d_feature_caps_t* pFeatureCaps ///< [in,out][release] 3D properties + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetSupported3DCapabilities_t pfnGetSupported3DCapabilities = (ctl_pfnGetSupported3DCapabilities_t)GetProcAddress(hinstLibPtr, "ctlGetSupported3DCapabilities"); + if (pfnGetSupported3DCapabilities) + { + result = pfnGetSupported3DCapabilities(hDAhandle, pFeatureCaps); + } + } + + return result; +} + + +/** +* @brief Get/Set 3D feature +* +* @details +* - 3D 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 +ctlGetSet3DFeature( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + ctl_3d_feature_getset_t* pFeature ///< [in][release] 3D feature get/set parameter + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetSet3DFeature_t pfnGetSet3DFeature = (ctl_pfnGetSet3DFeature_t)GetProcAddress(hinstLibPtr, "ctlGetSet3DFeature"); + if (pfnGetSet3DFeature) + { + result = pfnGetSet3DFeature(hDAhandle, pFeature); + } + } + + return result; +} + + +/** +* @brief Check Driver version +* +* @details +* - The application checks driver version +* +* @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_t CTL_APICALL +ctlCheckDriverVersion( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter + ctl_version_info_t version_info ///< [in][release] Driver version info + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnCheckDriverVersion_t pfnCheckDriverVersion = (ctl_pfnCheckDriverVersion_t)GetProcAddress(hinstLibPtr, "ctlCheckDriverVersion"); + if (pfnCheckDriverVersion) + { + result = pfnCheckDriverVersion(hDeviceAdapter, version_info); + } + } + + return result; +} + + +/** +* @brief Enumerate devices +* +* @details +* - The application enumerates all device adapters 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` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlEnumerateDevices( + 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 device instances. If count + ///< is zero, then the api will update the value with the total + ///< number of drivers available. If count is non-zero, then the api will + ///< only retrieve the number of drivers. + ///< If count is larger than the number of drivers available, then the api + ///< will update the value with the correct number of drivers available. + ctl_device_adapter_handle_t* phDevices ///< [in,out][optional][release][range(0, *pCount)] array of driver + ///< instance handles + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnEnumerateDevices_t pfnEnumerateDevices = (ctl_pfnEnumerateDevices_t)GetProcAddress(hinstLibPtr, "ctlEnumerateDevices"); + if (pfnEnumerateDevices) + { + result = pfnEnumerateDevices(hAPIHandle, pCount, phDevices); + } + } + + return result; +} + + +/** +* @brief Enumerate display outputs +* +* @details +* - Enumerates display output capabilities +* +* @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_t CTL_APICALL +ctlEnumerateDisplayOutputs( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter + uint32_t* pCount, ///< [in,out][release] pointer to the number of display output instances. + ///< 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 drivers available, then the api + ///< will update the value with the correct number of drivers available. + ctl_display_output_handle_t* phDisplayOutputs ///< [in,out][optional][release][range(0, *pCount)] array of display output + ///< instance handles + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnEnumerateDisplayOutputs_t pfnEnumerateDisplayOutputs = (ctl_pfnEnumerateDisplayOutputs_t)GetProcAddress(hinstLibPtr, "ctlEnumerateDisplayOutputs"); + if (pfnEnumerateDisplayOutputs) + { + result = pfnEnumerateDisplayOutputs(hDeviceAdapter, pCount, phDisplayOutputs); + } + } + + return result; +} + + +/** +* @brief Enumerate I2C Pin Pairs +* +* @details +* - Returns available list of I2C Pin-Pairs on a requested adapter +* +* @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_POINTER - "The incoming pointer pCount is null" +* - ::CTL_RESULT_ERROR_INVALID_SIZE - "The supplied Count is not equal to actual number of i2c pin-pair instances" +*/ +ctl_result_t CTL_APICALL +ctlEnumerateI2CPinPairs( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to device adapter + uint32_t* pCount, ///< [in,out][release] pointer to the number of i2c pin-pair instances. If + ///< count is zero, then the api will update the value with the total + ///< number of i2c pin-pair instances available. If count is non-zero and + ///< matches the avaialble number of pin-pairs, then the api will only + ///< return the avaialble number of i2c pin-pair instances in phI2cPinPairs. + ctl_i2c_pin_pair_handle_t* phI2cPinPairs ///< [out][optional][release][range(0, *pCount)] array of i2c pin pair + ///< instance handles. Need to be allocated by Caller when supplying the + ///< *pCount > 0. + ///< If Count is not equal to actual number of i2c pin-pair instances, it + ///< will return CTL_RESULT_ERROR_INVALID_SIZE. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnEnumerateI2CPinPairs_t pfnEnumerateI2CPinPairs = (ctl_pfnEnumerateI2CPinPairs_t)GetProcAddress(hinstLibPtr, "ctlEnumerateI2CPinPairs"); + if (pfnEnumerateI2CPinPairs) + { + result = pfnEnumerateI2CPinPairs(hDeviceAdapter, pCount, phI2cPinPairs); + } + } + + return result; +} + + +/** +* @brief Get Device Properties +* +* @details +* - The application gets device 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 == pProperties` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlGetDeviceProperties( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to control device adapter + ctl_device_adapter_properties_t* pProperties ///< [in,out][release] Query result for device properties + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetDeviceProperties_t pfnGetDeviceProperties = (ctl_pfnGetDeviceProperties_t)GetProcAddress(hinstLibPtr, "ctlGetDeviceProperties"); + if (pfnGetDeviceProperties) + { + result = pfnGetDeviceProperties(hDAhandle, pProperties); + } + } + + return result; +} + + +/** +* @brief Get Display Properties +* +* @details +* - The application gets display properties +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pProperties` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlGetDisplayProperties( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_display_properties_t* pProperties ///< [in,out][release] Query result for display properties + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetDisplayProperties_t pfnGetDisplayProperties = (ctl_pfnGetDisplayProperties_t)GetProcAddress(hinstLibPtr, "ctlGetDisplayProperties"); + if (pfnGetDisplayProperties) + { + result = pfnGetDisplayProperties(hDisplayOutput, pProperties); + } + } + + return result; +} + + +/** +* @brief Get Adapter Display encoder Properties +* +* @details +* - The application gets the graphic adapters display encoder properties +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pProperties` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlGetAdaperDisplayEncoderProperties( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_adapter_display_encoder_properties_t* pProperties ///< [in,out][release] Query result for adapter display encoder properties + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetAdaperDisplayEncoderProperties_t pfnGetAdaperDisplayEncoderProperties = (ctl_pfnGetAdaperDisplayEncoderProperties_t)GetProcAddress(hinstLibPtr, "ctlGetAdaperDisplayEncoderProperties"); + if (pfnGetAdaperDisplayEncoderProperties) + { + result = pfnGetAdaperDisplayEncoderProperties(hDisplayOutput, pProperties); + } + } + + return result; +} + + +/** +* @brief Get Level0 Device handle +* +* @details +* - The application gets OneAPI Level0 Device handles +* +* @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 == pZeDevice` +* + `nullptr == hInstance` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlGetZeDevice( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + void* pZeDevice, ///< [out][release] ze_device handle + void** hInstance ///< [out][release] Module instance which caller can use to get export + ///< functions directly + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetZeDevice_t pfnGetZeDevice = (ctl_pfnGetZeDevice_t)GetProcAddress(hinstLibPtr, "ctlGetZeDevice"); + if (pfnGetZeDevice) + { + result = pfnGetZeDevice(hDAhandle, pZeDevice, hInstance); + } + } + + return result; +} + + +/** +* @brief Get Sharpness capability +* +* @details +* - Returns sharpness capability +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pSharpnessCaps` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlGetSharpnessCaps( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_sharpness_caps_t* pSharpnessCaps ///< [in,out][release] Query result for sharpness capability + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetSharpnessCaps_t pfnGetSharpnessCaps = (ctl_pfnGetSharpnessCaps_t)GetProcAddress(hinstLibPtr, "ctlGetSharpnessCaps"); + if (pfnGetSharpnessCaps) + { + result = pfnGetSharpnessCaps(hDisplayOutput, pSharpnessCaps); + } + } + + return result; +} + + +/** +* @brief Get Sharpness setting +* +* @details +* - Returns current sharpness settings +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pSharpnessSettings` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlGetCurrentSharpness( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_sharpness_settings_t* pSharpnessSettings ///< [in,out][release] Query result for sharpness current settings + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetCurrentSharpness_t pfnGetCurrentSharpness = (ctl_pfnGetCurrentSharpness_t)GetProcAddress(hinstLibPtr, "ctlGetCurrentSharpness"); + if (pfnGetCurrentSharpness) + { + result = pfnGetCurrentSharpness(hDisplayOutput, pSharpnessSettings); + } + } + + return result; +} + + +/** +* @brief Set Sharpness setting +* +* @details +* - Set current sharpness settings +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pSharpnessSettings` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlSetCurrentSharpness( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_sharpness_settings_t* pSharpnessSettings ///< [in][release] Set sharpness current settings + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnSetCurrentSharpness_t pfnSetCurrentSharpness = (ctl_pfnSetCurrentSharpness_t)GetProcAddress(hinstLibPtr, "ctlSetCurrentSharpness"); + if (pfnSetCurrentSharpness) + { + result = pfnSetCurrentSharpness(hDisplayOutput, pSharpnessSettings); + } + } + + return result; +} + + +/** +* @brief I2C Access +* +* @details +* - Interface to access I2C using display handle as identifier. I2C +* driver override flags are supported only for HDMI displays. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pI2cAccessArgs` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" +* - ::CTL_RESULT_ERROR_INVALID_SIZE - "Invalid I2C data size" +* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" +* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +* - ::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 - "Kernal mode driver call failure" +*/ +ctl_result_t CTL_APICALL +ctlI2CAccess( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_i2c_access_args_t* pI2cAccessArgs ///< [in,out] I2c access arguments + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnI2CAccess_t pfnI2CAccess = (ctl_pfnI2CAccess_t)GetProcAddress(hinstLibPtr, "ctlI2CAccess"); + if (pfnI2CAccess) + { + result = pfnI2CAccess(hDisplayOutput, pI2cAccessArgs); + } + } + + return result; +} + + +/** +* @brief I2C Access On Pin Pair +* +* @details +* - Interface to access I2C using pin-pair handle as identifier. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hI2cPinPair` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pI2cAccessArgs` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" +* - ::CTL_RESULT_ERROR_INVALID_SIZE - "Invalid I2C data size" +* - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid Args passed" +* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" +* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +* - ::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 - "Kernal mode driver call failure" +* - ::CTL_RESULT_ERROR_INVALID_NULL_HANDLE - "Invalid or Null handle passed" +* - ::CTL_RESULT_ERROR_EXTERNAL_DISPLAY_ATTACHED - "Write to Address not allowed when Display is connected" +*/ +ctl_result_t CTL_APICALL +ctlI2CAccessOnPinPair( + ctl_i2c_pin_pair_handle_t hI2cPinPair, ///< [in] Handle to I2C pin pair. + ctl_i2c_access_pinpair_args_t* pI2cAccessArgs ///< [in,out] I2c access arguments. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnI2CAccessOnPinPair_t pfnI2CAccessOnPinPair = (ctl_pfnI2CAccessOnPinPair_t)GetProcAddress(hinstLibPtr, "ctlI2CAccessOnPinPair"); + if (pfnI2CAccessOnPinPair) + { + result = pfnI2CAccessOnPinPair(hI2cPinPair, pI2cAccessArgs); + } + } + + return result; +} + + +/** +* @brief Aux Access +* +* @details +* - The application does Aux access, PSR needs to be disabled for AUX +* call. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pAuxAccessArgs` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" +* - ::CTL_RESULT_ERROR_INVALID_SIZE - "Invalid AUX data size" +* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" +* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +* - ::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_INVALID_AUX_ACCESS_FLAG - "Invalid flag for AUX access" +* - ::CTL_RESULT_ERROR_KMD_CALL - "Kernal mode driver call failure" +*/ +ctl_result_t CTL_APICALL +ctlAUXAccess( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_aux_access_args_t* pAuxAccessArgs ///< [in,out] Aux access arguments + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnAUXAccess_t pfnAUXAccess = (ctl_pfnAUXAccess_t)GetProcAddress(hinstLibPtr, "ctlAUXAccess"); + if (pfnAUXAccess) + { + result = pfnAUXAccess(hDisplayOutput, pAuxAccessArgs); + } + } + + return result; +} + + +/** +* @brief Get Power optimization features +* +* @details +* - Returns power optimization capabilities +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pPowerOptimizationCaps` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlGetPowerOptimizationCaps( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_power_optimization_caps_t* pPowerOptimizationCaps ///< [in,out][release] Query result for power optimization features + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetPowerOptimizationCaps_t pfnGetPowerOptimizationCaps = (ctl_pfnGetPowerOptimizationCaps_t)GetProcAddress(hinstLibPtr, "ctlGetPowerOptimizationCaps"); + if (pfnGetPowerOptimizationCaps) + { + result = pfnGetPowerOptimizationCaps(hDisplayOutput, pPowerOptimizationCaps); + } + } + + return result; +} + + +/** +* @brief Get Power optimization setting +* +* @details +* - Returns power optimization setting for a specific feature +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pPowerOptimizationSettings` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INVALID_POWERFEATURE_OPTIMIZATION_FLAG - "Unsupported PowerOptimizationFeature" +* - ::CTL_RESULT_ERROR_INVALID_POWERSOURCE_TYPE_FOR_DPST - "DPST is supported only in DC Mode" +*/ +ctl_result_t CTL_APICALL +ctlGetPowerOptimizationSetting( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_power_optimization_settings_t* pPowerOptimizationSettings ///< [in,out][release] Power optimization data to be fetched + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetPowerOptimizationSetting_t pfnGetPowerOptimizationSetting = (ctl_pfnGetPowerOptimizationSetting_t)GetProcAddress(hinstLibPtr, "ctlGetPowerOptimizationSetting"); + if (pfnGetPowerOptimizationSetting) + { + result = pfnGetPowerOptimizationSetting(hDisplayOutput, pPowerOptimizationSettings); + } + } + + return result; +} + + +/** +* @brief Set Power optimization setting +* +* @details +* - Set power optimization setting for a specific feature +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pPowerOptimizationSettings` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INVALID_POWERFEATURE_OPTIMIZATION_FLAG - "Unsupported PowerOptimizationFeature" +* - ::CTL_RESULT_ERROR_INVALID_POWERSOURCE_TYPE_FOR_DPST - "DPST is supported only in DC Mode" +* - ::CTL_RESULT_ERROR_SET_FBC_FEATURE_NOT_SUPPORTED - "Set FBC Feature not supported" +*/ +ctl_result_t CTL_APICALL +ctlSetPowerOptimizationSetting( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_power_optimization_settings_t* pPowerOptimizationSettings ///< [in][release] Power optimization data to be applied + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnSetPowerOptimizationSetting_t pfnSetPowerOptimizationSetting = (ctl_pfnSetPowerOptimizationSetting_t)GetProcAddress(hinstLibPtr, "ctlSetPowerOptimizationSetting"); + if (pfnSetPowerOptimizationSetting) + { + result = pfnSetPowerOptimizationSetting(hDisplayOutput, pPowerOptimizationSettings); + } + } + + return result; +} + + +/** +* @brief Set Brightness on companion display +* +* @details +* - Set Brightness for a target display. Currently support is only for +* companion display. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pSetBrightnessSetting` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid Brightness data passed as argument" +* - ::CTL_RESULT_ERROR_DISPLAY_NOT_ACTIVE - "Display not active" +* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Currently Brightness API is supported only on companion display" +*/ +ctl_result_t CTL_APICALL +ctlSetBrightnessSetting( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_set_brightness_t* pSetBrightnessSetting ///< [in][release] Brightness settings to be applied + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnSetBrightnessSetting_t pfnSetBrightnessSetting = (ctl_pfnSetBrightnessSetting_t)GetProcAddress(hinstLibPtr, "ctlSetBrightnessSetting"); + if (pfnSetBrightnessSetting) + { + result = pfnSetBrightnessSetting(hDisplayOutput, pSetBrightnessSetting); + } + } + + return result; +} + + +/** +* @brief Get Brightness setting +* +* @details +* - Get Brightness for a target display. Currently support is only for +* companion display. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pGetBrightnessSetting` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_DISPLAY_NOT_ACTIVE - "Display not active" +* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Currently Brightness API is supported only on companion display" +*/ +ctl_result_t CTL_APICALL +ctlGetBrightnessSetting( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_get_brightness_t* pGetBrightnessSetting ///< [out][release] Brightness settings data to be fetched + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetBrightnessSetting_t pfnGetBrightnessSetting = (ctl_pfnGetBrightnessSetting_t)GetProcAddress(hinstLibPtr, "ctlGetBrightnessSetting"); + if (pfnGetBrightnessSetting) + { + result = pfnGetBrightnessSetting(hDisplayOutput, pGetBrightnessSetting); + } + } + + return result; +} + + +/** +* @brief Pixel transformation get pipe configuration +* +* @details +* - The application does pixel transformation get pipe configuration +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pPixTxGetConfigArgs` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" +* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +* - ::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 - "Kernal mode driver call failure" +* - ::CTL_RESULT_ERROR_INVALID_PIXTX_GET_CONFIG_QUERY_TYPE - "Invalid query type" +* - ::CTL_RESULT_ERROR_INVALID_PIXTX_BLOCK_ID - "Invalid block id" +* - ::CTL_RESULT_ERROR_INSUFFICIENT_PIXTX_BLOCK_CONFIG_MEMORY - "Insufficient memery allocated for BlockConfigs" +* - ::CTL_RESULT_ERROR_3DLUT_INVALID_PIPE - "Invalid pipe for 3dlut" +* - ::CTL_RESULT_ERROR_3DLUT_INVALID_DATA - "Invalid 3dlut data" +* - ::CTL_RESULT_ERROR_3DLUT_NOT_SUPPORTED_IN_HDR - "3dlut not supported in HDR" +* - ::CTL_RESULT_ERROR_3DLUT_INVALID_OPERATION - "Invalid 3dlut operation" +* - ::CTL_RESULT_ERROR_3DLUT_UNSUCCESSFUL - "3dlut call unsuccessful" +*/ +ctl_result_t CTL_APICALL +ctlPixelTransformationGetConfig( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_pixtx_pipe_get_config_t* pPixTxGetConfigArgs///< [in,out] Pixel transformation get pipe configiguration arguments + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnPixelTransformationGetConfig_t pfnPixelTransformationGetConfig = (ctl_pfnPixelTransformationGetConfig_t)GetProcAddress(hinstLibPtr, "ctlPixelTransformationGetConfig"); + if (pfnPixelTransformationGetConfig) + { + result = pfnPixelTransformationGetConfig(hDisplayOutput, pPixTxGetConfigArgs); + } + } + + return result; +} + + +/** +* @brief Pixel transformation set pipe configuration +* +* @details +* - The application does pixel transformation set pipe configuration +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pPixTxSetConfigArgs` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" +* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +* - ::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 - "Kernal mode driver call failure" +* - ::CTL_RESULT_ERROR_INVALID_PIXTX_SET_CONFIG_OPERATION_TYPE - "Invalid operation type" +* - ::CTL_RESULT_ERROR_INVALID_SET_CONFIG_NUMBER_OF_SAMPLES - "Invalid number of samples" +* - ::CTL_RESULT_ERROR_INVALID_PIXTX_BLOCK_ID - "Invalid block id" +* - ::CTL_RESULT_ERROR_PERSISTANCE_NOT_SUPPORTED - "Persistance not supported" +* - ::CTL_RESULT_ERROR_3DLUT_INVALID_PIPE - "Invalid pipe for 3dlut" +* - ::CTL_RESULT_ERROR_3DLUT_INVALID_DATA - "Invalid 3dlut data" +* - ::CTL_RESULT_ERROR_3DLUT_NOT_SUPPORTED_IN_HDR - "3dlut not supported in HDR" +* - ::CTL_RESULT_ERROR_3DLUT_INVALID_OPERATION - "Invalid 3dlut operation" +* - ::CTL_RESULT_ERROR_3DLUT_UNSUCCESSFUL - "3dlut call unsuccessful" +*/ +ctl_result_t CTL_APICALL +ctlPixelTransformationSetConfig( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_pixtx_pipe_set_config_t* pPixTxSetConfigArgs///< [in,out] Pixel transformation set pipe configiguration arguments + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnPixelTransformationSetConfig_t pfnPixelTransformationSetConfig = (ctl_pfnPixelTransformationSetConfig_t)GetProcAddress(hinstLibPtr, "ctlPixelTransformationSetConfig"); + if (pfnPixelTransformationSetConfig) + { + result = pfnPixelTransformationSetConfig(hDisplayOutput, pPixTxSetConfigArgs); + } + } + + return result; +} + + +/** +* @brief Panel Descriptor Access +* +* @details +* - The application does EDID or Display ID access +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pPanelDescriptorAccessArgs` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" +* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" +* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +* - ::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 - "Kernal mode driver call failure" +*/ +ctl_result_t CTL_APICALL +ctlPanelDescriptorAccess( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_panel_descriptor_access_args_t* pPanelDescriptorAccessArgs ///< [in,out] Panel descriptor access arguments + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnPanelDescriptorAccess_t pfnPanelDescriptorAccess = (ctl_pfnPanelDescriptorAccess_t)GetProcAddress(hinstLibPtr, "ctlPanelDescriptorAccess"); + if (pfnPanelDescriptorAccess) + { + result = pfnPanelDescriptorAccess(hDisplayOutput, pPanelDescriptorAccessArgs); + } + } + + return result; +} + + +/** +* @brief Get Supported Retro Scaling Types +* +* @details +* - Returns supported retro scaling capabilities +* +* @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 == pRetroScalingCaps` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlGetSupportedRetroScalingCapability( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to adapter + ctl_retro_scaling_caps_t* pRetroScalingCaps ///< [in,out][release] Query result for supported retro scaling types + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetSupportedRetroScalingCapability_t pfnGetSupportedRetroScalingCapability = (ctl_pfnGetSupportedRetroScalingCapability_t)GetProcAddress(hinstLibPtr, "ctlGetSupportedRetroScalingCapability"); + if (pfnGetSupportedRetroScalingCapability) + { + result = pfnGetSupportedRetroScalingCapability(hDAhandle, pRetroScalingCaps); + } + } + + return result; +} + + +/** +* @brief Get/Set Retro Scaling +* +* @details +* - Get or Set the status of retro scaling.This Api will do a physical +* modeset resulting in flash on the screen +* +* @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 == pGetSetRetroScalingType` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlGetSetRetroScaling( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to adapter + ctl_retro_scaling_settings_t* pGetSetRetroScalingType ///< [in,out][release] Get or Set the retro scaling type + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetSetRetroScaling_t pfnGetSetRetroScaling = (ctl_pfnGetSetRetroScaling_t)GetProcAddress(hinstLibPtr, "ctlGetSetRetroScaling"); + if (pfnGetSetRetroScaling) + { + result = pfnGetSetRetroScaling(hDAhandle, pGetSetRetroScalingType); + } + } + + return result; +} + + +/** +* @brief Get Supported Scaling Types +* +* @details +* - Returns supported scaling capabilities +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pScalingCaps` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlGetSupportedScalingCapability( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_scaling_caps_t* pScalingCaps ///< [in,out][release] Query result for supported scaling types + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetSupportedScalingCapability_t pfnGetSupportedScalingCapability = (ctl_pfnGetSupportedScalingCapability_t)GetProcAddress(hinstLibPtr, "ctlGetSupportedScalingCapability"); + if (pfnGetSupportedScalingCapability) + { + result = pfnGetSupportedScalingCapability(hDisplayOutput, pScalingCaps); + } + } + + return result; +} + + +/** +* @brief Get Current Scaling +* +* @details +* - Returns current active scaling +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pGetCurrentScalingType` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlGetCurrentScaling( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_scaling_settings_t* pGetCurrentScalingType ///< [in,out][release] Query result for active scaling types + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetCurrentScaling_t pfnGetCurrentScaling = (ctl_pfnGetCurrentScaling_t)GetProcAddress(hinstLibPtr, "ctlGetCurrentScaling"); + if (pfnGetCurrentScaling) + { + result = pfnGetCurrentScaling(hDisplayOutput, pGetCurrentScalingType); + } + } + + return result; +} + + +/** +* @brief Set Scaling Type +* +* @details +* - Returns current active scaling +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pSetScalingType` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlSetCurrentScaling( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_scaling_settings_t* pSetScalingType ///< [in,out][release] Set scaling types + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnSetCurrentScaling_t pfnSetCurrentScaling = (ctl_pfnSetCurrentScaling_t)GetProcAddress(hinstLibPtr, "ctlSetCurrentScaling"); + if (pfnSetCurrentScaling) + { + result = pfnSetCurrentScaling(hDisplayOutput, pSetScalingType); + } + } + + return result; +} + + +/** +* @brief Get LACE Config +* +* @details +* - Returns current LACE Config +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pLaceConfig` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_LACE_INVALID_DATA_ARGUMENT_PASSED - "Lace Incorrrect AggressivePercent data or LuxVsAggressive Map data passed by user" +*/ +ctl_result_t CTL_APICALL +ctlGetLACEConfig( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_lace_config_t* pLaceConfig ///< [out]Lace configuration + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetLACEConfig_t pfnGetLACEConfig = (ctl_pfnGetLACEConfig_t)GetProcAddress(hinstLibPtr, "ctlGetLACEConfig"); + if (pfnGetLACEConfig) + { + result = pfnGetLACEConfig(hDisplayOutput, pLaceConfig); + } + } + + return result; +} + + +/** +* @brief Sets LACE Config +* +* @details +* - Sets LACE Config +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pLaceConfig` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_LACE_INVALID_DATA_ARGUMENT_PASSED - "Lace Incorrrect AggressivePercent data or LuxVsAggressive Map data passed by user" +*/ +ctl_result_t CTL_APICALL +ctlSetLACEConfig( + ctl_display_output_handle_t hDisplayOutput, ///< [in]Handle to display output + ctl_lace_config_t* pLaceConfig ///< [in]Lace configuration + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnSetLACEConfig_t pfnSetLACEConfig = (ctl_pfnSetLACEConfig_t)GetProcAddress(hinstLibPtr, "ctlSetLACEConfig"); + if (pfnSetLACEConfig) + { + result = pfnSetLACEConfig(hDisplayOutput, pLaceConfig); + } + } + + return result; +} + + +/** +* @brief Get Software PSR caps/Set software PSR State +* +* @details +* - Returns Software PSR status or Sets Software PSR capabilities. This is +* a reserved capability. By default, software PSR is not supported/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 == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pSoftwarePsrSetting` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlSoftwarePSR( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_sw_psr_settings_t* pSoftwarePsrSetting ///< [in,out][release] Get Software PSR caps/state or Set Software PSR + ///< state + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnSoftwarePSR_t pfnSoftwarePSR = (ctl_pfnSoftwarePSR_t)GetProcAddress(hinstLibPtr, "ctlSoftwarePSR"); + if (pfnSoftwarePSR) + { + result = pfnSoftwarePSR(hDisplayOutput, pSoftwarePsrSetting); + } + } + + return result; +} + + +/** +* @brief Get Intel Arc Sync information for monitor +* +* @details +* - Returns Intel Arc Sync information for selected monitor +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pIntelArcSyncMonitorParams` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlGetIntelArcSyncInfoForMonitor( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_intel_arc_sync_monitor_params_t* pIntelArcSyncMonitorParams ///< [in,out][release] Intel Arc Sync params for monitor + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetIntelArcSyncInfoForMonitor_t pfnGetIntelArcSyncInfoForMonitor = (ctl_pfnGetIntelArcSyncInfoForMonitor_t)GetProcAddress(hinstLibPtr, "ctlGetIntelArcSyncInfoForMonitor"); + if (pfnGetIntelArcSyncInfoForMonitor) + { + result = pfnGetIntelArcSyncInfoForMonitor(hDisplayOutput, pIntelArcSyncMonitorParams); + } + } + + return result; +} + + +/** +* @brief Get Intel Arc Sync profile +* +* @details +* - Returns Intel Arc Sync profile for selected monitor +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pIntelArcSyncProfileParams` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlGetIntelArcSyncProfile( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_intel_arc_sync_profile_params_t* pIntelArcSyncProfileParams ///< [in,out][release] Intel Arc Sync params for monitor + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetIntelArcSyncProfile_t pfnGetIntelArcSyncProfile = (ctl_pfnGetIntelArcSyncProfile_t)GetProcAddress(hinstLibPtr, "ctlGetIntelArcSyncProfile"); + if (pfnGetIntelArcSyncProfile) + { + result = pfnGetIntelArcSyncProfile(hDisplayOutput, pIntelArcSyncProfileParams); + } + } + + return result; +} + + +/** +* @brief Set Intel Arc Sync profile +* +* @details +* - Sets Intel Arc Sync profile for selected monitor. In a mux situation, +* this API should be called for all display IDs associated with a +* physical display. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pIntelArcSyncProfileParams` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +*/ +ctl_result_t CTL_APICALL +ctlSetIntelArcSyncProfile( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_intel_arc_sync_profile_params_t* pIntelArcSyncProfileParams ///< [in][release] Intel Arc Sync params for monitor + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnSetIntelArcSyncProfile_t pfnSetIntelArcSyncProfile = (ctl_pfnSetIntelArcSyncProfile_t)GetProcAddress(hinstLibPtr, "ctlSetIntelArcSyncProfile"); + if (pfnSetIntelArcSyncProfile) + { + result = pfnSetIntelArcSyncProfile(hDisplayOutput, pIntelArcSyncProfileParams); + } + } + + return result; +} + + +/** +* @brief EDID Management allows managing an output's EDID or Plugged Status. +* +* @details +* - To manage output's EDID or Display ID. Supports native DP SST and HDMI +* Display types. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pEdidManagementArgs` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" +* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +* - ::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 - "Kernal mode driver call failure" +* - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid combination of parameters" +* - ::CTL_RESULT_ERROR_DISPLAY_NOT_ATTACHED - "Error for Output Device not attached" +* - ::CTL_RESULT_ERROR_OUT_OF_DEVICE_MEMORY - "Insufficient device memory to satisfy call" +* - ::CTL_RESULT_ERROR_DATA_NOT_FOUND - "Requested EDID data not present." +*/ +ctl_result_t CTL_APICALL +ctlEdidManagement( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_edid_management_args_t* pEdidManagementArgs ///< [in,out] EDID management arguments + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnEdidManagement_t pfnEdidManagement = (ctl_pfnEdidManagement_t)GetProcAddress(hinstLibPtr, "ctlEdidManagement"); + if (pfnEdidManagement) + { + result = pfnEdidManagement(hDisplayOutput, pEdidManagementArgs); + } + } + + return result; +} + + +/** +* @brief Get/Set Custom mode. +* +* @details +* - To get or set custom mode. +* - Add custom source mode operation supports only single mode additon at +* a time. +* - Remove custom source mode operation supports single or multiple mode +* removal at a time. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pCustomModeArgs` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" +* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +* - ::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 - "Kernal mode driver call failure" +* - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid combination of parameters" +* - ::CTL_RESULT_ERROR_CUSTOM_MODE_STANDARD_CUSTOM_MODE_EXISTS - "Standard custom mode exists" +* - ::CTL_RESULT_ERROR_CUSTOM_MODE_NON_CUSTOM_MATCHING_MODE_EXISTS - "Non custom matching mode exists" +* - ::CTL_RESULT_ERROR_CUSTOM_MODE_INSUFFICIENT_MEMORY - "Custom mode insufficent memory" +*/ +ctl_result_t CTL_APICALL +ctlGetSetCustomMode( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_get_set_custom_mode_args_t* pCustomModeArgs ///< [in,out] Custom mode arguments + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetSetCustomMode_t pfnGetSetCustomMode = (ctl_pfnGetSetCustomMode_t)GetProcAddress(hinstLibPtr, "ctlGetSetCustomMode"); + if (pfnGetSetCustomMode) + { + result = pfnGetSetCustomMode(hDisplayOutput, pCustomModeArgs); + } + } + + return result; +} + + +/** +* @brief Get/Set Combined Display +* +* @details +* - To get or set combined display with given Child Targets on a Single +* GPU or across identical GPUs. Multi-GPU(MGPU) combined display is +* reserved i.e. it is not public and requires special application GUID. +* MGPU Combined Display will get activated or deactivated in next boot. +* MGPU scenario will internally link the associated adapters via Linked +* Display Adapter Call, with supplied hDeviceAdapter being the LDA +* Primary. If Genlock and enabled in Driver registry and supported by +* given Display Config, MGPU Combined Display will enable MGPU Genlock +* with supplied hDeviceAdapter being the Genlock Primary Adapter and the +* First Child Display being the Primary Display. +* +* @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 == pCombinedDisplayArgs` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" +* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" +* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +* - ::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_FEATURE_NOT_SUPPORTED - "Combined Display feature is not supported in this platform" +* - ::CTL_RESULT_ERROR_ADAPTER_NOT_SUPPORTED_ON_LDA_SECONDARY - "Unsupported (secondary) adapter handle passed" +*/ +ctl_result_t CTL_APICALL +ctlGetSetCombinedDisplay( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] Handle to control device adapter + ctl_combined_display_args_t* pCombinedDisplayArgs ///< [in,out] Setup and get combined display arguments + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetSetCombinedDisplay_t pfnGetSetCombinedDisplay = (ctl_pfnGetSetCombinedDisplay_t)GetProcAddress(hinstLibPtr, "ctlGetSetCombinedDisplay"); + if (pfnGetSetCombinedDisplay) + { + result = pfnGetSetCombinedDisplay(hDeviceAdapter, pCombinedDisplayArgs); + } + } + + return result; +} + + +/** +* @brief Get/Set Display Genlock +* +* @details +* - To get or set Display Genlock. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == hDeviceAdapter` +* + `nullptr == pGenlockArgs` +* + `nullptr == hFailureDeviceAdapter` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +* - ::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_INVALID_SIZE - "Invalid topology structure size" +* - ::CTL_RESULT_ERROR_KMD_CALL - "Kernel mode driver call failure" +*/ +ctl_result_t CTL_APICALL +ctlGetSetDisplayGenlock( + ctl_device_adapter_handle_t* hDeviceAdapter, ///< [in][release] Handle to control device adapter + ctl_genlock_args_t* pGenlockArgs, ///< [in,out] Display Genlock operation and information + uint32_t AdapterCount, ///< [in] Number of device adapters + ctl_device_adapter_handle_t* hFailureDeviceAdapter ///< [out] Handle to address the failure device adapter in an error case + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetSetDisplayGenlock_t pfnGetSetDisplayGenlock = (ctl_pfnGetSetDisplayGenlock_t)GetProcAddress(hinstLibPtr, "ctlGetSetDisplayGenlock"); + if (pfnGetSetDisplayGenlock) + { + result = pfnGetSetDisplayGenlock(hDeviceAdapter, pGenlockArgs, AdapterCount, hFailureDeviceAdapter); + } + } + + return result; +} + + +/** +* @brief Get Vblank Timestamp +* +* @details +* - To get a list of vblank timestamps in microseconds for each child +* target of a display. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pVblankTSArgs` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" +* - ::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_t CTL_APICALL +ctlGetVblankTimestamp( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_vblank_ts_args_t* pVblankTSArgs ///< [out] Get vblank timestamp arguments + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetVblankTimestamp_t pfnGetVblankTimestamp = (ctl_pfnGetVblankTimestamp_t)GetProcAddress(hinstLibPtr, "ctlGetVblankTimestamp"); + if (pfnGetVblankTimestamp) + { + result = pfnGetVblankTimestamp(hDisplayOutput, pVblankTSArgs); + } + } + + return result; +} + + +/** +* @brief Link Display Adapters +* +* @details +* - To Link Display Adapters. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hPrimaryAdapter` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pLdaArgs` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +* - ::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_ADAPTER_ALREADY_LINKED - "Adapter is already linked" +*/ +ctl_result_t CTL_APICALL +ctlLinkDisplayAdapters( + ctl_device_adapter_handle_t hPrimaryAdapter, ///< [in][release] Handle to Primary adapter in LDA chain + ctl_lda_args_t* pLdaArgs ///< [in] Link Display Adapters Arguments + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnLinkDisplayAdapters_t pfnLinkDisplayAdapters = (ctl_pfnLinkDisplayAdapters_t)GetProcAddress(hinstLibPtr, "ctlLinkDisplayAdapters"); + if (pfnLinkDisplayAdapters) + { + result = pfnLinkDisplayAdapters(hPrimaryAdapter, pLdaArgs); + } + } + + return result; +} + + +/** +* @brief Unlink Display Adapters +* +* @details +* - To Unlink Display Adapters +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hPrimaryAdapter` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::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_ADAPTER_NOT_SUPPORTED_ON_LDA_SECONDARY - "Unsupported (secondary) adapter handle passed" +*/ +ctl_result_t CTL_APICALL +ctlUnlinkDisplayAdapters( + ctl_device_adapter_handle_t hPrimaryAdapter ///< [in][release] Handle to Primary adapter in LDA chain + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnUnlinkDisplayAdapters_t pfnUnlinkDisplayAdapters = (ctl_pfnUnlinkDisplayAdapters_t)GetProcAddress(hinstLibPtr, "ctlUnlinkDisplayAdapters"); + if (pfnUnlinkDisplayAdapters) + { + result = pfnUnlinkDisplayAdapters(hPrimaryAdapter); + } + } + + return result; +} + + +/** +* @brief Get Linked Display Adapters +* +* @details +* - To return list of Linked Display Adapters. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hPrimaryAdapter` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pLdaArgs` +* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +* - ::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_ADAPTER_NOT_SUPPORTED_ON_LDA_SECONDARY - "Unsupported (secondary) adapter handle passed" +*/ +ctl_result_t CTL_APICALL +ctlGetLinkedDisplayAdapters( + ctl_device_adapter_handle_t hPrimaryAdapter, ///< [in][release] Handle to Primary adapter in LDA chain + ctl_lda_args_t* pLdaArgs ///< [out] Link Display Adapters Arguments + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetLinkedDisplayAdapters_t pfnGetLinkedDisplayAdapters = (ctl_pfnGetLinkedDisplayAdapters_t)GetProcAddress(hinstLibPtr, "ctlGetLinkedDisplayAdapters"); + if (pfnGetLinkedDisplayAdapters) + { + result = pfnGetLinkedDisplayAdapters(hPrimaryAdapter, pLdaArgs); + } + } + + return result; +} + + +/** +* @brief Get/Set Dynamic Contrast Enhancement +* +* @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 +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pDceArgs` +* - ::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 +ctlGetSetDynamicContrastEnhancement( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_dce_args_t* pDceArgs ///< [in,out] Dynamic Contrast Enhancement arguments + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetSetDynamicContrastEnhancement_t pfnGetSetDynamicContrastEnhancement = (ctl_pfnGetSetDynamicContrastEnhancement_t)GetProcAddress(hinstLibPtr, "ctlGetSetDynamicContrastEnhancement"); + if (pfnGetSetDynamicContrastEnhancement) + { + result = pfnGetSetDynamicContrastEnhancement(hDisplayOutput, pDceArgs); + } + } + + return result; +} + + +/** +* @brief Get/Set Color Format and Color Depth +* +* @details +* - 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 == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `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 +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; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetSetWireFormat_t pfnGetSetWireFormat = (ctl_pfnGetSetWireFormat_t)GetProcAddress(hinstLibPtr, "ctlGetSetWireFormat"); + if (pfnGetSetWireFormat) + { + result = pfnGetSetWireFormat(hDisplayOutput, pGetSetWireFormatSetting); + } + } + + return result; +} + + +/** +* @brief Get/Set Display settings +* +* @details +* - 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 == hDisplayOutput` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `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 +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; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetSetDisplaySettings_t pfnGetSetDisplaySettings = (ctl_pfnGetSetDisplaySettings_t)GetProcAddress(hinstLibPtr, "ctlGetSetDisplaySettings"); + if (pfnGetSetDisplaySettings) + { + result = pfnGetSetDisplaySettings(hDisplayOutput, pDisplaySettings); + } + } + + return result; +} + + +/** +* @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_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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnEccGetProperties_t pfnEccGetProperties = (ctl_pfnEccGetProperties_t)GetProcAddress(hinstLibPtr, "ctlEccGetProperties"); + if (pfnEccGetProperties) + { + result = pfnEccGetProperties(hDAhandle, pProperties); + } + } + + return result; +} + + +/** +* @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_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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnEccGetState_t pfnEccGetState = (ctl_pfnEccGetState_t)GetProcAddress(hinstLibPtr, "ctlEccGetState"); + if (pfnEccGetState) + { + result = pfnEccGetState(hDAhandle, pState); + } + } + + return result; +} + + +/** +* @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_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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnEccSetState_t pfnEccSetState = (ctl_pfnEccSetState_t)GetProcAddress(hinstLibPtr, "ctlEccSetState"); + if (pfnEccSetState) + { + result = pfnEccSetState(hDAhandle, pState); + } + } + + return result; +} + + +/** +* @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_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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnEnumEngineGroups_t pfnEnumEngineGroups = (ctl_pfnEnumEngineGroups_t)GetProcAddress(hinstLibPtr, "ctlEnumEngineGroups"); + if (pfnEnumEngineGroups) + { + result = pfnEnumEngineGroups(hDAhandle, pCount, phEngine); + } + } + + return result; +} + + +/** +* @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_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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnEngineGetProperties_t pfnEngineGetProperties = (ctl_pfnEngineGetProperties_t)GetProcAddress(hinstLibPtr, "ctlEngineGetProperties"); + if (pfnEngineGetProperties) + { + result = pfnEngineGetProperties(hEngine, pProperties); + } + } + + return result; +} + + +/** +* @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_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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnEngineGetActivity_t pfnEngineGetActivity = (ctl_pfnEngineGetActivity_t)GetProcAddress(hinstLibPtr, "ctlEngineGetActivity"); + if (pfnEngineGetActivity) + { + result = pfnEngineGetActivity(hEngine, pStats); + } + } + + return result; +} + + +/** +* @brief Get handle of fans +* +* @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 +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; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnEnumFans_t pfnEnumFans = (ctl_pfnEnumFans_t)GetProcAddress(hinstLibPtr, "ctlEnumFans"); + if (pfnEnumFans) + { + result = pfnEnumFans(hDAhandle, pCount, phFan); + } + } + + return result; +} + + +/** +* @brief Get fan 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 == hFan` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pProperties` +*/ +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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnFanGetProperties_t pfnFanGetProperties = (ctl_pfnFanGetProperties_t)GetProcAddress(hinstLibPtr, "ctlFanGetProperties"); + if (pfnFanGetProperties) + { + result = pfnFanGetProperties(hFan, pProperties); + } + } + + return result; +} + + +/** +* @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. +* - 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 == hFan` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pConfig` +*/ +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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnFanGetConfig_t pfnFanGetConfig = (ctl_pfnFanGetConfig_t)GetProcAddress(hinstLibPtr, "ctlFanGetConfig"); + if (pfnFanGetConfig) + { + result = pfnFanGetConfig(hFan, pConfig); + } + } + + return result; +} + + +/** +* @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. +* - 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 == hFan` +* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS +* + User does not have permissions to make these modifications. +*/ +ctl_result_t CTL_APICALL +ctlFanSetDefaultMode( + ctl_fan_handle_t hFan ///< [in] Handle for the component. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnFanSetDefaultMode_t pfnFanSetDefaultMode = (ctl_pfnFanSetDefaultMode_t)GetProcAddress(hinstLibPtr, "ctlFanSetDefaultMode"); + if (pfnFanSetDefaultMode) + { + result = pfnFanSetDefaultMode(hFan); + } + } + + return result; +} + + +/** +* @brief Configure the fan to rotate at a fixed speed (set mode to +* ::CTL_FAN_SPEED_MODE_FIXED) +* +* @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 == hFan` +* - 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. +*/ +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 + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnFanSetFixedSpeedMode_t pfnFanSetFixedSpeedMode = (ctl_pfnFanSetFixedSpeedMode_t)GetProcAddress(hinstLibPtr, "ctlFanSetFixedSpeedMode"); + if (pfnFanSetFixedSpeedMode) + { + result = pfnFanSetFixedSpeedMode(hFan, speed); + } + } + + return result; +} + + +/** +* @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. +* - 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 == hFan` +* - 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. +*/ +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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnFanSetSpeedTableMode_t pfnFanSetSpeedTableMode = (ctl_pfnFanSetSpeedTableMode_t)GetProcAddress(hinstLibPtr, "ctlFanSetSpeedTableMode"); + if (pfnFanSetSpeedTableMode) + { + result = pfnFanSetSpeedTableMode(hFan, speedTable); + } + } + + return result; +} + + +/** +* @brief Get current state of a fan - current mode and speed +* +* @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 == 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. +*/ +ctl_result_t CTL_APICALL +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; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnFanGetState_t pfnFanGetState = (ctl_pfnFanGetState_t)GetProcAddress(hinstLibPtr, "ctlFanGetState"); + if (pfnFanGetState) + { + result = pfnFanGetState(hFan, units, pSpeed); + } + } + + return result; +} + + +/** +* @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_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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetFirmwareProperties_t pfnGetFirmwareProperties = (ctl_pfnGetFirmwareProperties_t)GetProcAddress(hinstLibPtr, "ctlGetFirmwareProperties"); + if (pfnGetFirmwareProperties) + { + result = pfnGetFirmwareProperties(hDeviceAdapter, pProperties); + } + } + + return result; +} + + +/** +* @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_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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnEnumerateFirmwareComponents_t pfnEnumerateFirmwareComponents = (ctl_pfnEnumerateFirmwareComponents_t)GetProcAddress(hinstLibPtr, "ctlEnumerateFirmwareComponents"); + if (pfnEnumerateFirmwareComponents) + { + result = pfnEnumerateFirmwareComponents(hDeviceAdapter, pCount, phFirmware); + } + } + + return result; +} + + +/** +* @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_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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnGetFirmwareComponentProperties_t pfnGetFirmwareComponentProperties = (ctl_pfnGetFirmwareComponentProperties_t)GetProcAddress(hinstLibPtr, "ctlGetFirmwareComponentProperties"); + if (pfnGetFirmwareComponentProperties) + { + result = pfnGetFirmwareComponentProperties(hFirmware, pProperties); + } + } + + return result; +} + + +/** +* @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_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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnAllowPCIeLinkSpeedUpdate_t pfnAllowPCIeLinkSpeedUpdate = (ctl_pfnAllowPCIeLinkSpeedUpdate_t)GetProcAddress(hinstLibPtr, "ctlAllowPCIeLinkSpeedUpdate"); + if (pfnAllowPCIeLinkSpeedUpdate) + { + result = pfnAllowPCIeLinkSpeedUpdate(hDeviceAdapter, AllowPCIeLinkSpeedUpdate); + } + } + + return result; +} + + +/** +* @brief Get handle of frequency domains +* +* @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 +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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnEnumFrequencyDomains_t pfnEnumFrequencyDomains = (ctl_pfnEnumFrequencyDomains_t)GetProcAddress(hinstLibPtr, "ctlEnumFrequencyDomains"); + if (pfnEnumFrequencyDomains) + { + result = pfnEnumFrequencyDomains(hDAhandle, pCount, phFrequency); + } + } + + return result; +} + + +/** +* @brief Get frequency properties - available frequencies +* +* @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 == hFrequency` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pProperties` +*/ +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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnFrequencyGetProperties_t pfnFrequencyGetProperties = (ctl_pfnFrequencyGetProperties_t)GetProcAddress(hinstLibPtr, "ctlFrequencyGetProperties"); + if (pfnFrequencyGetProperties) + { + result = pfnFrequencyGetProperties(hFrequency, pProperties); + } + } + + return result; +} + + +/** +* @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. +* +* @returns +* - CTL_RESULT_SUCCESS +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hFrequency` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pCount` +*/ +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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnFrequencyGetAvailableClocks_t pfnFrequencyGetAvailableClocks = (ctl_pfnFrequencyGetAvailableClocks_t)GetProcAddress(hinstLibPtr, "ctlFrequencyGetAvailableClocks"); + if (pfnFrequencyGetAvailableClocks) + { + result = pfnFrequencyGetAvailableClocks(hFrequency, pCount, phFrequency); + } + } + + return result; +} + + +/** +* @brief Get current frequency limits +* +* @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 == hFrequency` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pLimits` +*/ +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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnFrequencyGetRange_t pfnFrequencyGetRange = (ctl_pfnFrequencyGetRange_t)GetProcAddress(hinstLibPtr, "ctlFrequencyGetRange"); + if (pfnFrequencyGetRange) + { + result = pfnFrequencyGetRange(hFrequency, pLimits); + } + } + + return result; +} + + +/** +* @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 == hFrequency` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pLimits` +* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS +* + User does not have permissions to make these modifications. +*/ +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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnFrequencySetRange_t pfnFrequencySetRange = (ctl_pfnFrequencySetRange_t)GetProcAddress(hinstLibPtr, "ctlFrequencySetRange"); + if (pfnFrequencySetRange) + { + result = pfnFrequencySetRange(hFrequency, pLimits); + } + } + + return result; +} + + +/** +* @brief Get current frequency state - frequency request, actual frequency, TDP +* limits +* +* @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 == hFrequency` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pState` +*/ +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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnFrequencyGetState_t pfnFrequencyGetState = (ctl_pfnFrequencyGetState_t)GetProcAddress(hinstLibPtr, "ctlFrequencyGetState"); + if (pfnFrequencyGetState) + { + result = pfnFrequencyGetState(hFrequency, pState); + } + } + + return result; +} + + +/** +* @brief Get frequency throttle time +* +* @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 == hFrequency` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pThrottleTime` +*/ +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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnFrequencyGetThrottleTime_t pfnFrequencyGetThrottleTime = (ctl_pfnFrequencyGetThrottleTime_t)GetProcAddress(hinstLibPtr, "ctlFrequencyGetThrottleTime"); + if (pfnFrequencyGetThrottleTime) + { + result = pfnFrequencyGetThrottleTime(hFrequency, pThrottleTime); + } + } + + return result; +} + + +/** +* @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_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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + 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); + } + } + + return result; +} + + +/** +* @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 +* - 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 +* - 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_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. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockPowerLimitGet_t pfnOverclockPowerLimitGet = (ctl_pfnOverclockPowerLimitGet_t)GetProcAddress(hinstLibPtr, "ctlOverclockPowerLimitGet"); + if (pfnOverclockPowerLimitGet) + { + result = pfnOverclockPowerLimitGet(hDeviceHandle, pSustainedPowerLimit); + } + } + + return result; +} + + +/** +* @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_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. + ) +{ + 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; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockResetToDefault_t pfnOverclockResetToDefault = (ctl_pfnOverclockResetToDefault_t)GetProcAddress(hinstLibPtr, "ctlOverclockResetToDefault"); + if (pfnOverclockResetToDefault) + { + result = pfnOverclockResetToDefault(hDeviceHandle); + } + } + + return result; +} + + +/** +* @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_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() + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockGpuFrequencyOffsetGetV2_t pfnOverclockGpuFrequencyOffsetGetV2 = (ctl_pfnOverclockGpuFrequencyOffsetGetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockGpuFrequencyOffsetGetV2"); + if (pfnOverclockGpuFrequencyOffsetGetV2) + { + result = pfnOverclockGpuFrequencyOffsetGetV2(hDeviceHandle, pOcFrequencyOffset); + } + } + + return result; +} + + +/** +* @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_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() + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockGpuFrequencyOffsetSetV2_t pfnOverclockGpuFrequencyOffsetSetV2 = (ctl_pfnOverclockGpuFrequencyOffsetSetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockGpuFrequencyOffsetSetV2"); + if (pfnOverclockGpuFrequencyOffsetSetV2) + { + result = pfnOverclockGpuFrequencyOffsetSetV2(hDeviceHandle, ocFrequencyOffset); + } + } + + return result; +} + + +/** +* @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_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() + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockGpuMaxVoltageOffsetGetV2_t pfnOverclockGpuMaxVoltageOffsetGetV2 = (ctl_pfnOverclockGpuMaxVoltageOffsetGetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockGpuMaxVoltageOffsetGetV2"); + if (pfnOverclockGpuMaxVoltageOffsetGetV2) + { + result = pfnOverclockGpuMaxVoltageOffsetGetV2(hDeviceHandle, pOcMaxVoltageOffset); + } + } + + return result; +} + + +/** +* @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_result_t CTL_APICALL +ctlOverclockGpuMaxVoltageOffsetSetV2( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + 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; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockGpuMaxVoltageOffsetSetV2_t pfnOverclockGpuMaxVoltageOffsetSetV2 = (ctl_pfnOverclockGpuMaxVoltageOffsetSetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockGpuMaxVoltageOffsetSetV2"); + if (pfnOverclockGpuMaxVoltageOffsetSetV2) + { + result = pfnOverclockGpuMaxVoltageOffsetSetV2(hDeviceHandle, ocMaxVoltageOffset); + } + } + + return result; +} + + +/** +* @brief Get the current Overclock Vram Memory Speed +* +* @details +* - 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 +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pOcVramMemSpeedLimit` +*/ +ctl_result_t CTL_APICALL +ctlOverclockVramMemSpeedLimitGetV2( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + 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; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockVramMemSpeedLimitGetV2_t pfnOverclockVramMemSpeedLimitGetV2 = (ctl_pfnOverclockVramMemSpeedLimitGetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockVramMemSpeedLimitGetV2"); + if (pfnOverclockVramMemSpeedLimitGetV2) + { + result = pfnOverclockVramMemSpeedLimitGetV2(hDeviceHandle, pOcVramMemSpeedLimit); + } + } + + return result; +} + + +/** +* @brief Set the desired Overclock Vram Memory Speed +* +* @details +* - 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 +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +*/ +ctl_result_t CTL_APICALL +ctlOverclockVramMemSpeedLimitSetV2( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + 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; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockVramMemSpeedLimitSetV2_t pfnOverclockVramMemSpeedLimitSetV2 = (ctl_pfnOverclockVramMemSpeedLimitSetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockVramMemSpeedLimitSetV2"); + if (pfnOverclockVramMemSpeedLimitSetV2) + { + result = pfnOverclockVramMemSpeedLimitSetV2(hDeviceHandle, ocVramMemSpeedLimit); + } + } + + return result; +} + + +/** +* @brief Get the Current Sustained power limit +* +* @details +* - The purpose of this function is to read the current sustained power +* limit. +* - 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 +* - 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_result_t CTL_APICALL +ctlOverclockPowerLimitGetV2( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + 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; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockPowerLimitGetV2_t pfnOverclockPowerLimitGetV2 = (ctl_pfnOverclockPowerLimitGetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockPowerLimitGetV2"); + if (pfnOverclockPowerLimitGetV2) + { + result = pfnOverclockPowerLimitGetV2(hDeviceHandle, pSustainedPowerLimit); + } + } + + return result; +} + + +/** +* @brief Set the Sustained power limit +* +* @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 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 +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +*/ +ctl_result_t CTL_APICALL +ctlOverclockPowerLimitSetV2( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + 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; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockPowerLimitSetV2_t pfnOverclockPowerLimitSetV2 = (ctl_pfnOverclockPowerLimitSetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockPowerLimitSetV2"); + if (pfnOverclockPowerLimitSetV2) + { + result = pfnOverclockPowerLimitSetV2(hDeviceHandle, sustainedPowerLimit); + } + } + + return result; +} + + +/** +* @brief Get the current temperature limit +* +* @details +* - 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 +* - 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 +ctlOverclockTemperatureLimitGetV2( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + 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; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockTemperatureLimitGetV2_t pfnOverclockTemperatureLimitGetV2 = (ctl_pfnOverclockTemperatureLimitGetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockTemperatureLimitGetV2"); + if (pfnOverclockTemperatureLimitGetV2) + { + result = pfnOverclockTemperatureLimitGetV2(hDeviceHandle, pTemperatureLimit); + } + } + + return result; +} + + +/** +* @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 +* - CTL_RESULT_ERROR_UNINITIALIZED +* - CTL_RESULT_ERROR_DEVICE_LOST +* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +* + `nullptr == hDeviceHandle` +*/ +ctl_result_t CTL_APICALL +ctlOverclockTemperatureLimitSetV2( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + 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; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockTemperatureLimitSetV2_t pfnOverclockTemperatureLimitSetV2 = (ctl_pfnOverclockTemperatureLimitSetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockTemperatureLimitSetV2"); + if (pfnOverclockTemperatureLimitSetV2) + { + result = pfnOverclockTemperatureLimitSetV2(hDeviceHandle, temperatureLimit); + } + } + + return result; +} + + +/** +* @brief Read VF Curve +* +* @details +* - 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 == 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 +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; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockReadVFCurve_t pfnOverclockReadVFCurve = (ctl_pfnOverclockReadVFCurve_t)GetProcAddress(hinstLibPtr, "ctlOverclockReadVFCurve"); + if (pfnOverclockReadVFCurve) + { + result = pfnOverclockReadVFCurve(hDeviceAdapter, VFCurveType, VFCurveDetail, pNumPoints, pVFCurveTable); + } + } + + return result; +} + + +/** +* @brief Write Custom VF curve +* +* @details +* - 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 == hDeviceAdapter` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pCustomVFCurveTable` +* - CTL_RESULT_ERROR_UNKNOWN - "Unknown Error" +*/ +ctl_result_t CTL_APICALL +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; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnOverclockWriteCustomVFCurve_t pfnOverclockWriteCustomVFCurve = (ctl_pfnOverclockWriteCustomVFCurve_t)GetProcAddress(hinstLibPtr, "ctlOverclockWriteCustomVFCurve"); + if (pfnOverclockWriteCustomVFCurve) + { + result = pfnOverclockWriteCustomVFCurve(hDeviceAdapter, NumPoints, pCustomVFCurveTable); + } + } + + return result; +} + + +/** +* @brief Get PCI properties - address, max speed +* +* @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_result_t CTL_APICALL +ctlPciGetProperties( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + ctl_pci_properties_t* pProperties ///< [in,out] Will contain the PCI properties. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnPciGetProperties_t pfnPciGetProperties = (ctl_pfnPciGetProperties_t)GetProcAddress(hinstLibPtr, "ctlPciGetProperties"); + if (pfnPciGetProperties) + { + result = pfnPciGetProperties(hDAhandle, pProperties); + } + } + + return result; +} + + +/** +* @brief Get current PCI state - current speed +* +* @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_t CTL_APICALL +ctlPciGetState( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + ctl_pci_state_t* pState ///< [in,out] Will contain the PCI properties. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnPciGetState_t pfnPciGetState = (ctl_pfnPciGetState_t)GetProcAddress(hinstLibPtr, "ctlPciGetState"); + if (pfnPciGetState) + { + result = pfnPciGetState(hDAhandle, pState); + } + } + + return result; +} + + +/** +* @brief Get handle of power domains +* +* @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 +ctlEnumPowerDomains( + 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_pwr_handle_t* phPower ///< [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_pfnEnumPowerDomains_t pfnEnumPowerDomains = (ctl_pfnEnumPowerDomains_t)GetProcAddress(hinstLibPtr, "ctlEnumPowerDomains"); + if (pfnEnumPowerDomains) + { + result = pfnEnumPowerDomains(hDAhandle, pCount, phPower); + } + } + + return result; +} + + +/** +* @brief Get properties related to a power domain +* +* @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 == hPower` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pProperties` +*/ +ctl_result_t CTL_APICALL +ctlPowerGetProperties( + ctl_pwr_handle_t hPower, ///< [in] Handle for the component. + ctl_power_properties_t* pProperties ///< [in,out] Structure that will contain property data. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnPowerGetProperties_t pfnPowerGetProperties = (ctl_pfnPowerGetProperties_t)GetProcAddress(hinstLibPtr, "ctlPowerGetProperties"); + if (pfnPowerGetProperties) + { + result = pfnPowerGetProperties(hPower, pProperties); + } + } + + return result; +} + + +/** +* @brief Get energy counter +* +* @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 == hPower` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pEnergy` +*/ +ctl_result_t CTL_APICALL +ctlPowerGetEnergyCounter( + ctl_pwr_handle_t hPower, ///< [in] Handle for the component. + ctl_power_energy_counter_t* pEnergy ///< [in,out] Will contain the latest snapshot of the energy counter and + ///< timestamp when the last counter value was measured. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnPowerGetEnergyCounter_t pfnPowerGetEnergyCounter = (ctl_pfnPowerGetEnergyCounter_t)GetProcAddress(hinstLibPtr, "ctlPowerGetEnergyCounter"); + if (pfnPowerGetEnergyCounter) + { + result = pfnPowerGetEnergyCounter(hPower, pEnergy); + } + } + + return result; +} + + +/** +* @brief Get power limits +* +* @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 == hPower` +*/ +ctl_result_t CTL_APICALL +ctlPowerGetLimits( + ctl_pwr_handle_t hPower, ///< [in] Handle for the component. + ctl_power_limits_t* pPowerLimits ///< [in,out][optional] Structure that will contain the power limits. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnPowerGetLimits_t pfnPowerGetLimits = (ctl_pfnPowerGetLimits_t)GetProcAddress(hinstLibPtr, "ctlPowerGetLimits"); + if (pfnPowerGetLimits) + { + result = pfnPowerGetLimits(hPower, pPowerLimits); + } + } + + return result; +} + + +/** +* @brief Set power limits +* +* @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 == hPower` +* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS +* + User does not have permissions to make these modifications. +* - ::CTL_RESULT_ERROR_NOT_AVAILABLE +* + The device is in use, meaning that the GPU is under Over clocking, applying power limits under overclocking is not supported. +*/ +ctl_result_t CTL_APICALL +ctlPowerSetLimits( + ctl_pwr_handle_t hPower, ///< [in] Handle for the component. + const ctl_power_limits_t* pPowerLimits ///< [in][optional] Structure that will contain the power limits. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnPowerSetLimits_t pfnPowerSetLimits = (ctl_pfnPowerSetLimits_t)GetProcAddress(hinstLibPtr, "ctlPowerSetLimits"); + if (pfnPowerSetLimits) + { + result = pfnPowerSetLimits(hPower, pPowerLimits); + } + } + + return result; +} + + +/** +* @brief Get handle of temperature sensors +* +* @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 +ctlEnumTemperatureSensors( + 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_temp_handle_t* phTemperature ///< [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_pfnEnumTemperatureSensors_t pfnEnumTemperatureSensors = (ctl_pfnEnumTemperatureSensors_t)GetProcAddress(hinstLibPtr, "ctlEnumTemperatureSensors"); + if (pfnEnumTemperatureSensors) + { + result = pfnEnumTemperatureSensors(hDAhandle, pCount, phTemperature); + } + } + + return result; +} + + +/** +* @brief Get temperature sensor 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 == hTemperature` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pProperties` +*/ +ctl_result_t CTL_APICALL +ctlTemperatureGetProperties( + ctl_temp_handle_t hTemperature, ///< [in] Handle for the component. + ctl_temp_properties_t* pProperties ///< [in,out] Will contain the temperature sensor properties. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnTemperatureGetProperties_t pfnTemperatureGetProperties = (ctl_pfnTemperatureGetProperties_t)GetProcAddress(hinstLibPtr, "ctlTemperatureGetProperties"); + if (pfnTemperatureGetProperties) + { + result = pfnTemperatureGetProperties(hTemperature, pProperties); + } + } + + return result; +} + + +/** +* @brief Get the temperature from a specified sensor +* +* @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 == hTemperature` +* - CTL_RESULT_ERROR_INVALID_NULL_POINTER +* + `nullptr == pTemperature` +*/ +ctl_result_t CTL_APICALL +ctlTemperatureGetState( + ctl_temp_handle_t hTemperature, ///< [in] Handle for the component. + double* pTemperature ///< [in,out] Will contain the temperature read from the specified sensor + ///< in degrees Celsius. + ) +{ + ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; + + + HINSTANCE hinstLibPtr = GetLoaderHandle(); + + if (NULL != hinstLibPtr) + { + ctl_pfnTemperatureGetState_t pfnTemperatureGetState = (ctl_pfnTemperatureGetState_t)GetProcAddress(hinstLibPtr, "ctlTemperatureGetState"); + if (pfnTemperatureGetState) + { + result = pfnTemperatureGetState(hTemperature, pTemperature); + } + } + + return result; +} + + +// +// End of wrapper function implementation +// +///////////////////////////////////////////////////////////////////////////////// diff --git a/IntelPresentMon/ControlLib/igcl/IgclErrorCodeProvider.cpp b/IntelPresentMon/ControlLib/igcl/IgclErrorCodeProvider.cpp new file mode 100644 index 00000000..fbaf96d9 --- /dev/null +++ b/IntelPresentMon/ControlLib/igcl/IgclErrorCodeProvider.cpp @@ -0,0 +1,21 @@ +#include "IgclErrorCodeProvider.h" +#include "../../CommonUtilities/log/ErrorCode.h" +#include "../../CommonUtilities/ref/GeneratedReflection.h" +#include "igcl_api.h" + +using namespace pmon::util; + +namespace pwr::intel +{ + std::type_index IgclErrorCodeProvider::GetTargetType() const + { + return typeid(ctl_result_t); + } + log::IErrorCodeResolver::Strings IgclErrorCodeProvider::Resolve(const pmon::util::log::ErrorCode& ec) const + { + return log::IErrorCodeResolver::Strings{ + .type = "ctl_result_t", + .symbol = ref::DumpGenerated((ctl_result_t)*ec.AsSigned()), + }; + } +} diff --git a/IntelPresentMon/ControlLib/igcl/IgclErrorCodeProvider.h b/IntelPresentMon/ControlLib/igcl/IgclErrorCodeProvider.h new file mode 100644 index 00000000..ba4146dd --- /dev/null +++ b/IntelPresentMon/ControlLib/igcl/IgclErrorCodeProvider.h @@ -0,0 +1,12 @@ +#pragma once +#include "../../CommonUtilities/log/IErrorCodeProvider.h" + +namespace pwr::intel +{ + class IgclErrorCodeProvider : public pmon::util::log::IErrorCodeProvider + { + public: + std::type_index GetTargetType() const override; + pmon::util::log::IErrorCodeResolver::Strings Resolve(const pmon::util::log::ErrorCode&) const override; + }; +} diff --git a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp new file mode 100644 index 00000000..89227fc6 --- /dev/null +++ b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp @@ -0,0 +1,927 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#include "IgclTelemetryProvider.h" + +#include "../Exceptions.h" +#include "../Logging.h" + +#include +#include +#include +#include +#include + +using namespace pmon; +using namespace util; + +namespace pmon::tel::igcl +{ + namespace + { + constexpr uint32_t kMaxFanCount_ = CTL_FAN_COUNT; + } + + IgclTelemetryProvider::IgclTelemetryProvider() + { + ctl_init_args_t ctlInitArgs{ + .Size = sizeof(ctl_init_args_t), + .AppVersion = CTL_MAKE_VERSION(CTL_IMPL_MAJOR_VERSION, CTL_IMPL_MINOR_VERSION), + .flags = CTL_INIT_FLAG_USE_LEVEL_ZERO, + }; + + const auto initResult = ctlInit(&ctlInitArgs, &apiHandle_); + if (initResult != CTL_RESULT_SUCCESS) { + if (initResult != CTL_RESULT_ERROR_NOT_INITIALIZED) { + pmlog_error("ctlInit failed").code(initResult); + } + throw Except("Unable to initialize Intel Graphics Control Library"); + } + + std::vector handles{}; + { + uint32_t count = 0; + const auto enumCountResult = ctlEnumerateDevices(apiHandle_, &count, nullptr); + if (enumCountResult != CTL_RESULT_SUCCESS) { + pmlog_error("ctlEnumerateDevices(count) failed").code(enumCountResult); + throw std::runtime_error{ "IGCL device enumeration (count) failed" }; + } + + handles.resize((size_t)count); + const auto enumListResult = ctlEnumerateDevices(apiHandle_, &count, handles.data()); + if (enumListResult != CTL_RESULT_SUCCESS) { + pmlog_error("ctlEnumerateDevices(list) failed").code(enumListResult); + throw std::runtime_error{ "IGCL device enumeration (list) failed" }; + } + } + + for (const auto handle : handles) { + const auto providerDeviceId = nextProviderDeviceId_; + const auto emplaceResult = devicesById_.try_emplace(providerDeviceId); + if (!emplaceResult.second) { + throw std::runtime_error{ "Duplicate IGCL provider device id encountered" }; + } + + auto& device = emplaceResult.first->second; + if (!TryInitializeDevice_(device, handle)) { + devicesById_.erase(emplaceResult.first); + continue; + } + + device.providerDeviceId = providerDeviceId; + device.caps = BuildCapsForDevice_(device); + ++nextProviderDeviceId_; + } + } + + IgclTelemetryProvider::~IgclTelemetryProvider() + { + devicesById_.clear(); + if (apiHandle_ != nullptr) { + ctlClose(apiHandle_); + apiHandle_ = nullptr; + } + } + + ProviderCapabilityMap IgclTelemetryProvider::GetCaps() + { + ProviderCapabilityMap capsByDeviceId{}; + for (const auto& entry : devicesById_) { + capsByDeviceId.emplace(entry.first, entry.second.caps); + } + return capsByDeviceId; + } + + const TelemetryDeviceFingerprint& IgclTelemetryProvider::GetFingerPrint( + ProviderDeviceId providerDeviceId) const + { + return devicesById_.at(providerDeviceId).fingerprint; + } + + TelemetryMetricValue IgclTelemetryProvider::PollMetric( + ProviderDeviceId providerDeviceId, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) + { + const auto iDevice = devicesById_.find(providerDeviceId); + if (iDevice == devicesById_.end()) { + throw std::out_of_range{ "IGCL provider device not found" }; + } + + auto& device = iDevice->second; + + switch (metricId) { + case PM_METRIC_GPU_VENDOR: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return (int)device.fingerprint.vendor; + case PM_METRIC_GPU_NAME: + throw std::invalid_argument{ "PM_METRIC_GPU_NAME is static-only and is not served by poll path" }; + case PM_METRIC_GPU_SUSTAINED_POWER_LIMIT: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto limits = PollPowerLimitsEndpoint_(device, requestQpc); + if (!limits || !limits->sustainedPowerLimit.enabled) { + return 0.0; + } + return (double)limits->sustainedPowerLimit.power / 1000.0; + } + case PM_METRIC_GPU_MEM_SIZE: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto memState = PollMemoryStateEndpoint_(device, requestQpc); + if (!memState) { + return (uint64_t)0; + } + return (uint64_t)memState->size; + } + case PM_METRIC_GPU_MEM_USED: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto memState = PollMemoryStateEndpoint_(device, requestQpc); + if (!memState) { + return (uint64_t)0; + } + return (uint64_t)(memState->size - memState->free); + } + case PM_METRIC_GPU_MEM_UTILIZATION: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto memState = PollMemoryStateEndpoint_(device, requestQpc); + if (!memState || memState->size == 0) { + return 0.0; + } + return 100.0 * ((double)(memState->size - memState->free) / (double)memState->size); + } + case PM_METRIC_GPU_MEM_MAX_BANDWIDTH: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto memBandwidth = PollMemoryBandwidthEndpoint_(device, requestQpc); + if (!memBandwidth) { + return (uint64_t)0; + } + return (uint64_t)memBandwidth->maxBandwidth; + } + default: + return PollTelemetryMetric_(device, metricId, arrayIndex, requestQpc); + } + } + + void IgclTelemetryProvider::ValidateScalarMetricIndex_(PM_METRIC metricId, uint32_t arrayIndex) + { + if (arrayIndex != 0) { + throw std::out_of_range{ "IGCL scalar metric queried with nonzero array index" }; + } + (void)metricId; + } + + bool IgclTelemetryProvider::TryInitializeDevice_( + DeviceState_& device, + ctl_device_adapter_handle_t handle) const + { + device.handle = handle; + device.properties = { + .Size = sizeof(ctl_device_adapter_properties_t), + .pDeviceID = &device.deviceLuid, + .device_id_size = sizeof(device.deviceLuid), + }; + + const auto propertiesResult = ctlGetDeviceProperties(device.handle, &device.properties); + if (propertiesResult != CTL_RESULT_SUCCESS) { + pmlog_error("ctlGetDeviceProperties failed").code(propertiesResult); + return false; + } + + if (device.properties.device_type != CTL_DEVICE_TYPE_GRAPHICS) { + return false; + } + + device.fingerprint.deviceType = PM_DEVICE_TYPE_GRAPHICS_ADAPTER; + device.fingerprint.vendor = PM_DEVICE_VENDOR_INTEL; + device.fingerprint.deviceName = device.properties.name; + + device.isAlchemist = std::regex_search(device.fingerprint.deviceName, std::regex{ R"(Arc.*A\d{3})" }); + + EnumerateMemoryModules_(device); + EnumeratePowerDomains_(device); + EnumerateFans_(device); + + return true; + } + + void IgclTelemetryProvider::EnumerateMemoryModules_(DeviceState_& device) const + { + uint32_t memoryModuleCount = 0; + const auto enumCountResult = ctlEnumMemoryModules(device.handle, &memoryModuleCount, nullptr); + if (enumCountResult != CTL_RESULT_SUCCESS) { + pmlog_warn("ctlEnumMemoryModules(count) failed").code(enumCountResult) + .pmwatch(device.fingerprint.deviceName); + return; + } + + device.memoryModules.resize((size_t)memoryModuleCount); + const auto enumListResult = ctlEnumMemoryModules( + device.handle, &memoryModuleCount, device.memoryModules.data()); + if (enumListResult != CTL_RESULT_SUCCESS) { + pmlog_warn("ctlEnumMemoryModules(list) failed").code(enumListResult) + .pmwatch(device.fingerprint.deviceName); + device.memoryModules.clear(); + return; + } + } + + void IgclTelemetryProvider::EnumeratePowerDomains_(DeviceState_& device) const + { + uint32_t powerDomainCount = 0; + const auto enumCountResult = ctlEnumPowerDomains(device.handle, &powerDomainCount, nullptr); + if (enumCountResult != CTL_RESULT_SUCCESS) { + pmlog_warn("ctlEnumPowerDomains(count) failed").code(enumCountResult) + .pmwatch(device.fingerprint.deviceName); + return; + } + + device.powerDomains.resize((size_t)powerDomainCount); + const auto enumListResult = ctlEnumPowerDomains( + device.handle, &powerDomainCount, device.powerDomains.data()); + if (enumListResult != CTL_RESULT_SUCCESS) { + pmlog_warn("ctlEnumPowerDomains(list) failed").code(enumListResult) + .pmwatch(device.fingerprint.deviceName); + device.powerDomains.clear(); + return; + } + } + + void IgclTelemetryProvider::EnumerateFans_(DeviceState_& device) const + { + device.maxFanSpeedsRpm.clear(); + device.maxFanSpeedsRpm.resize((size_t)kMaxFanCount_, 0); + + uint32_t fanCount = 0; + const auto enumCountResult = ctlEnumFans(device.handle, &fanCount, nullptr); + if (enumCountResult != CTL_RESULT_SUCCESS) { + pmlog_warn("ctlEnumFans(count) failed").code(enumCountResult) + .pmwatch(device.fingerprint.deviceName); + return; + } + + if (fanCount == 0) { + return; + } + + std::vector fanHandles{}; + fanHandles.resize((size_t)fanCount); + const auto enumListResult = ctlEnumFans(device.handle, &fanCount, fanHandles.data()); + if (enumListResult != CTL_RESULT_SUCCESS) { + pmlog_warn("ctlEnumFans(list) failed").code(enumListResult) + .pmwatch(device.fingerprint.deviceName); + return; + } + + const auto fanCountToRead = (uint32_t)std::min((size_t)fanCount, (size_t)kMaxFanCount_); + for (uint32_t iFan = 0; iFan < fanCountToRead; ++iFan) { + const auto hFan = fanHandles[(size_t)iFan]; + if (hFan == nullptr) { + continue; + } + + ctl_fan_properties_t fanProperties{ .Size = sizeof(ctl_fan_properties_t) }; + const auto fanPropsResult = ctlFanGetProperties(hFan, &fanProperties); + if (fanPropsResult != CTL_RESULT_SUCCESS) { + pmlog_warn("ctlFanGetProperties failed").code(fanPropsResult) + .pmwatch(device.fingerprint.deviceName).pmwatch(iFan); + continue; + } + + device.maxFanSpeedsRpm[(size_t)iFan] = fanProperties.maxRPM; + } + } + + ipc::MetricCapabilities IgclTelemetryProvider::BuildCapsForDevice_(DeviceState_& device) const + { + ipc::MetricCapabilities caps{}; + + // Static capabilities can exist even if they do not route through dynamic polling. + caps.Set(PM_METRIC_GPU_VENDOR, 1); + caps.Set(PM_METRIC_GPU_NAME, 1); + + const auto powerLimits = PollPowerLimitsEndpoint_(device, 0); + if (powerLimits && powerLimits->sustainedPowerLimit.enabled) { + caps.Set(PM_METRIC_GPU_SUSTAINED_POWER_LIMIT, 1); + } + + const auto memoryState = PollMemoryStateEndpoint_(device, 0); + if (memoryState) { + caps.Set(PM_METRIC_GPU_MEM_SIZE, 1); + caps.Set(PM_METRIC_GPU_MEM_USED, 1); + caps.Set(PM_METRIC_GPU_MEM_UTILIZATION, 1); + (void)memoryState; + } + + const auto memoryBandwidth = PollMemoryBandwidthEndpoint_(device, 0); + if (memoryBandwidth) { + caps.Set(PM_METRIC_GPU_MEM_MAX_BANDWIDTH, 1); + device.gpuMemMaxBwCacheValueBps = memoryBandwidth->maxBandwidth; + } + + const auto sample = PollTelemetryEndpoint_(device, 0); + + if (IsUsageTelemetryItemSupported_(sample.gpuEnergyCounter)) { + caps.Set(PM_METRIC_GPU_POWER, 1); + } + if (IsUsageTelemetryItemSupported_(sample.totalCardEnergyCounter)) { + caps.Set(PM_METRIC_GPU_CARD_POWER, 1); + } + if (IsInstantaneousTelemetryItemSupported_(sample.gpuVoltage)) { + caps.Set(PM_METRIC_GPU_VOLTAGE, 1); + } + if (IsInstantaneousTelemetryItemSupported_(sample.gpuCurrentClockFrequency)) { + caps.Set(PM_METRIC_GPU_FREQUENCY, 1); + } + if (IsInstantaneousTelemetryItemSupported_(sample.gpuCurrentTemperature)) { + caps.Set(PM_METRIC_GPU_TEMPERATURE, 1); + } + if (IsUsagePercentTelemetryItemSupported_(sample.globalActivityCounter)) { + caps.Set(PM_METRIC_GPU_UTILIZATION, 1); + } + if (IsUsagePercentTelemetryItemSupported_(sample.renderComputeActivityCounter)) { + caps.Set(PM_METRIC_GPU_RENDER_COMPUTE_UTILIZATION, 1); + } + if (IsUsagePercentTelemetryItemSupported_(sample.mediaActivityCounter)) { + caps.Set(PM_METRIC_GPU_MEDIA_UTILIZATION, 1); + } + + caps.Set(PM_METRIC_GPU_POWER_LIMITED, 1); + caps.Set(PM_METRIC_GPU_TEMPERATURE_LIMITED, 1); + caps.Set(PM_METRIC_GPU_VOLTAGE_LIMITED, 1); + caps.Set(PM_METRIC_GPU_UTILIZATION_LIMITED, 1); + if (device.isAlchemist) { + caps.Set(PM_METRIC_GPU_CURRENT_LIMITED, 1); + } + + if (IsInstantaneousTelemetryItemSupported_(sample.gpuEffectiveClock)) { + caps.Set(PM_METRIC_GPU_EFFECTIVE_FREQUENCY, 1); + } + if (IsInstantaneousTelemetryItemSupported_(sample.gpuVrTemp)) { + caps.Set(PM_METRIC_GPU_VOLTAGE_REGULATOR_TEMPERATURE, 1); + } + if (IsInstantaneousTelemetryItemSupported_(sample.vramCurrentEffectiveFrequency)) { + caps.Set(PM_METRIC_GPU_MEM_EFFECTIVE_FREQUENCY, 1); + caps.Set(PM_METRIC_GPU_MEM_EFFECTIVE_BANDWIDTH, 1); + } + if (IsInstantaneousTelemetryItemSupported_(sample.gpuOverVoltagePercent)) { + caps.Set(PM_METRIC_GPU_OVERVOLTAGE_PERCENT, 1); + } + if (IsInstantaneousTelemetryItemSupported_(sample.gpuTemperaturePercent)) { + caps.Set(PM_METRIC_GPU_TEMPERATURE_PERCENT, 1); + } + if (IsInstantaneousTelemetryItemSupported_(sample.gpuPowerPercent)) { + caps.Set(PM_METRIC_GPU_POWER_PERCENT, 1); + } + + if (IsUsageTelemetryItemSupported_(sample.vramEnergyCounter)) { + caps.Set(PM_METRIC_GPU_MEM_POWER, 1); + } + if (IsInstantaneousTelemetryItemSupported_(sample.vramVoltage)) { + caps.Set(PM_METRIC_GPU_MEM_VOLTAGE, 1); + } + if (IsInstantaneousTelemetryItemSupported_(sample.vramCurrentClockFrequency)) { + caps.Set(PM_METRIC_GPU_MEM_FREQUENCY, 1); + } + if (IsInstantaneousTelemetryItemSupported_(sample.vramCurrentTemperature)) { + caps.Set(PM_METRIC_GPU_MEM_TEMPERATURE, 1); + } + + const bool hasV1ReadBandwidth = IsInstantaneousTelemetryItemSupported_(sample.vramReadBandwidth); + const bool hasV1WriteBandwidth = IsInstantaneousTelemetryItemSupported_(sample.vramWriteBandwidth); + const bool hasCounterReadBandwidth = IsUsageTelemetryItemSupported_(sample.vramReadBandwidthCounter); + const bool hasCounterWriteBandwidth = IsUsageTelemetryItemSupported_(sample.vramWriteBandwidthCounter); + if (hasV1ReadBandwidth && hasV1WriteBandwidth) { + device.useNewBandwidthTelemetry = true; + caps.Set(PM_METRIC_GPU_MEM_READ_BANDWIDTH, 1); + caps.Set(PM_METRIC_GPU_MEM_WRITE_BANDWIDTH, 1); + } + else if (hasCounterReadBandwidth && hasCounterWriteBandwidth) { + device.useNewBandwidthTelemetry = false; + caps.Set(PM_METRIC_GPU_MEM_READ_BANDWIDTH, 1); + caps.Set(PM_METRIC_GPU_MEM_WRITE_BANDWIDTH, 1); + } + + device.fanSpeedCount = 0; + while (device.fanSpeedCount < kMaxFanCount_ && + IsInstantaneousTelemetryItemSupported_(sample.fanSpeed[(size_t)device.fanSpeedCount])) { + ++device.fanSpeedCount; + } + for (uint32_t iFan = device.fanSpeedCount; iFan < kMaxFanCount_; ++iFan) { + if (IsInstantaneousTelemetryItemSupported_(sample.fanSpeed[(size_t)iFan])) { + pmlog_warn("Detected sparse fan-speed telemetry population; assuming dense indices") + .pmwatch(device.fingerprint.deviceName) + .pmwatch(device.fanSpeedCount) + .pmwatch(iFan); + break; + } + } + + device.fanSpeedPercentCount = 0; + while (device.fanSpeedPercentCount < device.fanSpeedCount && + device.fanSpeedPercentCount < (uint32_t)device.maxFanSpeedsRpm.size() && + device.maxFanSpeedsRpm[(size_t)device.fanSpeedPercentCount] > 0) { + ++device.fanSpeedPercentCount; + } + for (uint32_t iFan = device.fanSpeedPercentCount; iFan < device.fanSpeedCount; ++iFan) { + if (iFan < (uint32_t)device.maxFanSpeedsRpm.size() && + device.maxFanSpeedsRpm[(size_t)iFan] > 0) { + pmlog_warn("Detected sparse fan-speed-percent telemetry population; assuming dense indices") + .pmwatch(device.fingerprint.deviceName) + .pmwatch(device.fanSpeedPercentCount) + .pmwatch(iFan); + break; + } + } + + if (device.fanSpeedCount > 0) { + caps.Set(PM_METRIC_GPU_FAN_SPEED, device.fanSpeedCount); + } + if (device.fanSpeedPercentCount > 0) { + caps.Set(PM_METRIC_GPU_FAN_SPEED_PERCENT, device.fanSpeedPercentCount); + } + + return caps; + } + + const ctl_power_telemetry_t& IgclTelemetryProvider::PollTelemetryEndpoint_( + DeviceState_& device, + int64_t requestQpc) const + { + if (requestQpc != 0 && device.telemetryEndpointCache.requestQpc == requestQpc) { + return device.telemetryEndpointCache.output; + } + + if (requestQpc != 0 && device.telemetryEndpointCache.requestQpc != 0 && + device.telemetryEndpointCache.requestQpc != requestQpc) { + device.previousTelemetryEndpointCache = device.telemetryEndpointCache; + } + + ctl_power_telemetry_t currentSample{ + .Size = sizeof(ctl_power_telemetry_t), + .Version = 1, + }; + + const auto pollResult = ctlPowerTelemetryGet(device.handle, ¤tSample); + if (pollResult != CTL_RESULT_SUCCESS) { + pmlog_warn("ctlPowerTelemetryGet failed").code(pollResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.fingerprint.deviceName); + currentSample = { + .Size = sizeof(ctl_power_telemetry_t), + .Version = 1, + }; + } + + device.telemetryEndpointCache.Store(requestQpc, currentSample); + return device.telemetryEndpointCache.output; + } + + std::optional IgclTelemetryProvider::PollMemoryStateEndpoint_( + DeviceState_& device, + int64_t requestQpc) const + { + if (device.memoryStateEndpointCache.HasValue(requestQpc)) { + if (device.memoryStateEndpointCache.output.Size == sizeof(ctl_mem_state_t)) { + return device.memoryStateEndpointCache.output; + } + return {}; + } + + ctl_mem_state_t memoryState{ .Size = sizeof(ctl_mem_state_t) }; + bool hasValue = false; + + if (!device.memoryModules.empty()) { + const auto result = ctlMemoryGetState(device.memoryModules[0], &memoryState); + if (result == CTL_RESULT_SUCCESS) { + hasValue = true; + } + else { + pmlog_warn("ctlMemoryGetState failed").code(result).every(std::chrono::seconds{ 60 }) + .pmwatch(device.fingerprint.deviceName); + } + } + + if (!hasValue) { + // Mark cached sample invalid while still memoizing the requestQpc. + memoryState.Size = 0; + } + device.memoryStateEndpointCache.Store(requestQpc, memoryState); + if (hasValue) { + return device.memoryStateEndpointCache.output; + } + return {}; + } + + std::optional IgclTelemetryProvider::PollMemoryBandwidthEndpoint_( + DeviceState_& device, + int64_t requestQpc) const + { + ctl_mem_bandwidth_t memoryBandwidth{ + .Size = sizeof(ctl_mem_bandwidth_t), + .Version = 1, + }; + + if (!device.memoryModules.empty()) { + const auto result = ctlMemoryGetBandwidth(device.memoryModules[0], &memoryBandwidth); + if (result == CTL_RESULT_SUCCESS) { + device.gpuMemMaxBwCacheValueBps = memoryBandwidth.maxBandwidth; + return memoryBandwidth; + } + else { + pmlog_warn("ctlMemoryGetBandwidth failed").code(result).every(std::chrono::seconds{ 60 }) + .pmwatch(device.fingerprint.deviceName); + } + } + + (void)requestQpc; + return {}; + } + + std::optional IgclTelemetryProvider::PollPowerLimitsEndpoint_( + DeviceState_& device, + int64_t requestQpc) const + { + ctl_power_limits_t powerLimits{ + .Size = sizeof(ctl_power_limits_t), + }; + + if (!device.powerDomains.empty()) { + const auto result = ctlPowerGetLimits(device.powerDomains[0], &powerLimits); + if (result == CTL_RESULT_SUCCESS) { + return powerLimits; + } + else { + pmlog_warn("ctlPowerGetLimits failed").code(result).every(std::chrono::seconds{ 60 }) + .pmwatch(device.fingerprint.deviceName); + } + } + + (void)requestQpc; + return {}; + } + + TelemetryMetricValue IgclTelemetryProvider::PollTelemetryMetric_( + DeviceState_& device, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) const + { + const auto& currentSample = PollTelemetryEndpoint_(device, requestQpc); + const auto& previousSampleCache = device.previousTelemetryEndpointCache; + const ctl_power_telemetry_t* pPreviousSample = nullptr; + double timeDelta = 0.0; + if (previousSampleCache.requestQpc != 0 && + currentSample.timeStamp.type == CTL_DATA_TYPE_DOUBLE && + previousSampleCache.output.timeStamp.type == CTL_DATA_TYPE_DOUBLE) { + pPreviousSample = &previousSampleCache.output; + timeDelta = currentSample.timeStamp.value.datadouble - + previousSampleCache.output.timeStamp.value.datadouble; + } + + double value = 0.0; + + switch (metricId) { + case PM_METRIC_GPU_POWER: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (pPreviousSample && + TryGetUsageTelemetryItem_( + device, metricId, currentSample.gpuEnergyCounter, pPreviousSample->gpuEnergyCounter, timeDelta, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_CARD_POWER: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (pPreviousSample && + TryGetUsageTelemetryItem_( + device, metricId, currentSample.totalCardEnergyCounter, pPreviousSample->totalCardEnergyCounter, timeDelta, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_VOLTAGE: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (TryGetInstantaneousTelemetryItem_(currentSample.gpuVoltage, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_FREQUENCY: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (TryGetInstantaneousTelemetryItem_(currentSample.gpuCurrentClockFrequency, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_TEMPERATURE: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (TryGetInstantaneousTelemetryItem_(currentSample.gpuCurrentTemperature, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_UTILIZATION: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (pPreviousSample && + TryGetUsagePercentTelemetryItem_( + currentSample.globalActivityCounter, pPreviousSample->globalActivityCounter, timeDelta, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_RENDER_COMPUTE_UTILIZATION: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (pPreviousSample && + TryGetUsagePercentTelemetryItem_( + currentSample.renderComputeActivityCounter, pPreviousSample->renderComputeActivityCounter, timeDelta, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_MEDIA_UTILIZATION: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (pPreviousSample && + TryGetUsagePercentTelemetryItem_( + currentSample.mediaActivityCounter, pPreviousSample->mediaActivityCounter, timeDelta, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_POWER_LIMITED: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return currentSample.gpuPowerLimited; + case PM_METRIC_GPU_TEMPERATURE_LIMITED: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return currentSample.gpuTemperatureLimited; + case PM_METRIC_GPU_CURRENT_LIMITED: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return currentSample.gpuCurrentLimited; + case PM_METRIC_GPU_VOLTAGE_LIMITED: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return currentSample.gpuVoltageLimited; + case PM_METRIC_GPU_UTILIZATION_LIMITED: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return currentSample.gpuUtilizationLimited; + case PM_METRIC_GPU_MEM_POWER: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (pPreviousSample && + TryGetUsageTelemetryItem_( + device, metricId, currentSample.vramEnergyCounter, pPreviousSample->vramEnergyCounter, timeDelta, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_MEM_VOLTAGE: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (TryGetInstantaneousTelemetryItem_(currentSample.vramVoltage, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_MEM_FREQUENCY: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (TryGetInstantaneousTelemetryItem_(currentSample.vramCurrentClockFrequency, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_MEM_EFFECTIVE_FREQUENCY: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (TryGetInstantaneousTelemetryItem_(currentSample.vramCurrentEffectiveFrequency, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_MEM_TEMPERATURE: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (TryGetInstantaneousTelemetryItem_(currentSample.vramCurrentTemperature, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_MEM_WRITE_BANDWIDTH: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (device.useNewBandwidthTelemetry) { + if (TryGetInstantaneousTelemetryItem_(currentSample.vramWriteBandwidth, value)) { + return ConvertMegabytesPerSecondToBitsPerSecond_(value); + } + device.useNewBandwidthTelemetry = false; + } + if (pPreviousSample && + TryGetUsageTelemetryItem_( + device, + metricId, + currentSample.vramWriteBandwidthCounter, + pPreviousSample->vramWriteBandwidthCounter, + timeDelta, + value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_MEM_READ_BANDWIDTH: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (device.useNewBandwidthTelemetry) { + if (TryGetInstantaneousTelemetryItem_(currentSample.vramReadBandwidth, value)) { + return ConvertMegabytesPerSecondToBitsPerSecond_(value); + } + device.useNewBandwidthTelemetry = false; + } + if (pPreviousSample && + TryGetUsageTelemetryItem_( + device, + metricId, + currentSample.vramReadBandwidthCounter, + pPreviousSample->vramReadBandwidthCounter, + timeDelta, + value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_EFFECTIVE_FREQUENCY: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (TryGetInstantaneousTelemetryItem_(currentSample.gpuEffectiveClock, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_VOLTAGE_REGULATOR_TEMPERATURE: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (TryGetInstantaneousTelemetryItem_(currentSample.gpuVrTemp, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_MEM_EFFECTIVE_BANDWIDTH: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (TryGetInstantaneousTelemetryItem_(currentSample.vramCurrentEffectiveFrequency, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_OVERVOLTAGE_PERCENT: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (TryGetInstantaneousTelemetryItem_(currentSample.gpuOverVoltagePercent, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_TEMPERATURE_PERCENT: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (TryGetInstantaneousTelemetryItem_(currentSample.gpuTemperaturePercent, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_POWER_PERCENT: + ValidateScalarMetricIndex_(metricId, arrayIndex); + if (TryGetInstantaneousTelemetryItem_(currentSample.gpuPowerPercent, value)) { + return value; + } + return 0.0; + case PM_METRIC_GPU_FAN_SPEED: + { + if (arrayIndex >= device.fanSpeedCount) { + throw Except<>{ "IGCL array index out of range" }; + } + if (TryGetInstantaneousTelemetryItem_(currentSample.fanSpeed[(size_t)arrayIndex], value)) { + return value; + } + return 0.0; + } + case PM_METRIC_GPU_FAN_SPEED_PERCENT: + { + if (arrayIndex >= device.fanSpeedPercentCount) { + throw Except<>{ "IGCL array index out of range" }; + } + if (!TryGetInstantaneousTelemetryItem_(currentSample.fanSpeed[(size_t)arrayIndex], value)) { + return 0.0; + } + if (arrayIndex >= (uint32_t)device.maxFanSpeedsRpm.size()) { + return 0.0; + } + const auto maxFanRpm = device.maxFanSpeedsRpm[(size_t)arrayIndex]; + if (maxFanRpm <= 0) { + return 0.0; + } + return value / (double)maxFanRpm; + } + case PM_METRIC_GPU_MEM_POWER_LIMITED: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return false; + case PM_METRIC_GPU_MEM_TEMPERATURE_LIMITED: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return false; + case PM_METRIC_GPU_MEM_CURRENT_LIMITED: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return false; + case PM_METRIC_GPU_MEM_VOLTAGE_LIMITED: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return false; + case PM_METRIC_GPU_MEM_UTILIZATION_LIMITED: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return false; + default: + throw std::invalid_argument{ "Unsupported metric for IGCL provider" }; + } + } + + bool IgclTelemetryProvider::TryGetInstantaneousTelemetryItem_( + const ctl_oc_telemetry_item_t& telemetryItem, + double& value) + { + if (telemetryItem.bSupported && telemetryItem.type == CTL_DATA_TYPE_DOUBLE) { + value = telemetryItem.value.datadouble; + return true; + } + + value = 0.0; + return false; + } + + bool IgclTelemetryProvider::TryGetUsagePercentTelemetryItem_( + const ctl_oc_telemetry_item_t& currentItem, + const ctl_oc_telemetry_item_t& previousItem, + double timeDelta, + double& value) + { + if (!currentItem.bSupported || currentItem.type != CTL_DATA_TYPE_DOUBLE || timeDelta <= 0.0) { + value = 0.0; + return false; + } + + const auto dataDelta = currentItem.value.datadouble - previousItem.value.datadouble; + value = (dataDelta / timeDelta) * 100.0; + return true; + } + + bool IgclTelemetryProvider::TryGetUsageTelemetryItem_( + DeviceState_& device, + PM_METRIC metricId, + const ctl_oc_telemetry_item_t& currentItem, + const ctl_oc_telemetry_item_t& previousItem, + double timeDelta, + double& value) + { + if (!currentItem.bSupported || timeDelta <= 0.0) { + value = 0.0; + return false; + } + + if (currentItem.type == CTL_DATA_TYPE_DOUBLE) { + const auto dataDelta = currentItem.value.datadouble - previousItem.value.datadouble; + value = dataDelta / timeDelta; + + if (metricId == PM_METRIC_GPU_MEM_POWER) { + if (currentItem.value.datadouble < previousItem.value.datadouble) { + value = device.gpuMemPowerCacheValueW; + } + else { + device.gpuMemPowerCacheValueW = value; + } + } + + return true; + } + + if (currentItem.type == CTL_DATA_TYPE_INT64) { + const auto dataDelta = currentItem.value.data64 - previousItem.value.data64; + value = (double)dataDelta / timeDelta; + return true; + } + + if (currentItem.type == CTL_DATA_TYPE_UINT64) { + const auto dataDelta = currentItem.value.datau64 - previousItem.value.datau64; + value = (double)dataDelta / timeDelta; + + if (metricId == PM_METRIC_GPU_MEM_READ_BANDWIDTH && !device.useNewBandwidthTelemetry) { + const auto overflowOrWrap = currentItem.value.datau64 < previousItem.value.datau64; + const auto overMax = dataDelta > device.gpuMemMaxBwCacheValueBps; + if (overflowOrWrap || overMax) { + value = device.gpuMemReadBwCacheValueBps; + } + else { + device.gpuMemReadBwCacheValueBps = value; + } + } + + return true; + } + + value = 0.0; + return false; + } + + bool IgclTelemetryProvider::IsInstantaneousTelemetryItemSupported_( + const ctl_oc_telemetry_item_t& telemetryItem) + { + return telemetryItem.bSupported && telemetryItem.type == CTL_DATA_TYPE_DOUBLE; + } + + bool IgclTelemetryProvider::IsUsageTelemetryItemSupported_( + const ctl_oc_telemetry_item_t& telemetryItem) + { + if (!telemetryItem.bSupported) { + return false; + } + + return telemetryItem.type == CTL_DATA_TYPE_DOUBLE || + telemetryItem.type == CTL_DATA_TYPE_INT64 || + telemetryItem.type == CTL_DATA_TYPE_UINT64; + } + + bool IgclTelemetryProvider::IsUsagePercentTelemetryItemSupported_( + const ctl_oc_telemetry_item_t& telemetryItem) + { + return telemetryItem.bSupported && telemetryItem.type == CTL_DATA_TYPE_DOUBLE; + } + + double IgclTelemetryProvider::ConvertMegabytesPerSecondToBitsPerSecond_(double megabytesPerSecond) + { + return megabytesPerSecond * 8.0 * 1000000.0; + } +} diff --git a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.h b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.h new file mode 100644 index 00000000..19ff283b --- /dev/null +++ b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.h @@ -0,0 +1,113 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#pragma once +#define NOMINMAX +#include + +#include "../TelemetryCache.h" +#include "../TelemetryProvider.h" +#include "igcl_api.h" + +#include +#include +#include +#include + +namespace pmon::tel::igcl +{ + class IgclTelemetryProvider : public TelemetryProvider + { + public: + IgclTelemetryProvider(); + ~IgclTelemetryProvider() override; + ProviderCapabilityMap GetCaps() override; + const TelemetryDeviceFingerprint& GetFingerPrint(ProviderDeviceId providerDeviceId) const override; + TelemetryMetricValue PollMetric( + ProviderDeviceId providerDeviceId, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) override; + + private: + struct DeviceState_ + { + ProviderDeviceId providerDeviceId = 0; + TelemetryDeviceFingerprint fingerprint{}; + ipc::MetricCapabilities caps{}; + + ctl_device_adapter_handle_t handle = nullptr; + LUID deviceLuid{}; + ctl_device_adapter_properties_t properties{}; + std::vector memoryModules{}; + std::vector powerDomains{}; + std::vector maxFanSpeedsRpm{}; + uint32_t fanSpeedCount = 0; + uint32_t fanSpeedPercentCount = 0; + bool isAlchemist = false; + + bool useNewBandwidthTelemetry = true; + + pmon::tele::EndpointCache telemetryEndpointCache{}; + pmon::tele::EndpointCache previousTelemetryEndpointCache{}; + + pmon::tele::EndpointCache memoryStateEndpointCache{}; + + // Runtime telemetry workarounds carried over from the legacy Intel path. + double gpuMemReadBwCacheValueBps = 0.0; + uint64_t gpuMemMaxBwCacheValueBps = 0; + double gpuMemPowerCacheValueW = 0.0; + }; + + static void ValidateScalarMetricIndex_(PM_METRIC metricId, uint32_t arrayIndex); + bool TryInitializeDevice_(DeviceState_& device, ctl_device_adapter_handle_t handle) const; + void EnumerateMemoryModules_(DeviceState_& device) const; + void EnumeratePowerDomains_(DeviceState_& device) const; + void EnumerateFans_(DeviceState_& device) const; + ipc::MetricCapabilities BuildCapsForDevice_(DeviceState_& device) const; + + const ctl_power_telemetry_t& PollTelemetryEndpoint_( + DeviceState_& device, + int64_t requestQpc) const; + std::optional PollMemoryStateEndpoint_( + DeviceState_& device, + int64_t requestQpc) const; + std::optional PollMemoryBandwidthEndpoint_( + DeviceState_& device, + int64_t requestQpc) const; + std::optional PollPowerLimitsEndpoint_( + DeviceState_& device, + int64_t requestQpc) const; + + TelemetryMetricValue PollTelemetryMetric_( + DeviceState_& device, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) const; + + static bool TryGetInstantaneousTelemetryItem_( + const ctl_oc_telemetry_item_t& telemetryItem, + double& value); + static bool TryGetUsagePercentTelemetryItem_( + const ctl_oc_telemetry_item_t& currentItem, + const ctl_oc_telemetry_item_t& previousItem, + double timeDelta, + double& value); + static bool TryGetUsageTelemetryItem_( + DeviceState_& device, + PM_METRIC metricId, + const ctl_oc_telemetry_item_t& currentItem, + const ctl_oc_telemetry_item_t& previousItem, + double timeDelta, + double& value); + + static bool IsInstantaneousTelemetryItemSupported_(const ctl_oc_telemetry_item_t& telemetryItem); + static bool IsUsageTelemetryItemSupported_(const ctl_oc_telemetry_item_t& telemetryItem); + static bool IsUsagePercentTelemetryItemSupported_(const ctl_oc_telemetry_item_t& telemetryItem); + static double ConvertMegabytesPerSecondToBitsPerSecond_(double megabytesPerSecond); + + private: + ctl_api_handle_t apiHandle_ = nullptr; + std::unordered_map devicesById_{}; + ProviderDeviceId nextProviderDeviceId_ = 1; + }; +} diff --git a/IntelPresentMon/ControlLib/cApiWrapper.cpp b/IntelPresentMon/ControlLib/igcl/cApiWrapper.cpp similarity index 99% rename from IntelPresentMon/ControlLib/cApiWrapper.cpp rename to IntelPresentMon/ControlLib/igcl/cApiWrapper.cpp index 492a5832..8bd953c9 100644 --- a/IntelPresentMon/ControlLib/cApiWrapper.cpp +++ b/IntelPresentMon/ControlLib/igcl/cApiWrapper.cpp @@ -1,4 +1,4 @@ -//=========================================================================== +//=========================================================================== //Copyright (C) 2025 Intel Corporation // // diff --git a/IntelPresentMon/ControlLib/igcl/igcl_api.h b/IntelPresentMon/ControlLib/igcl/igcl_api.h new file mode 100644 index 00000000..2b1e6e06 --- /dev/null +++ b/IntelPresentMon/ControlLib/igcl/igcl_api.h @@ -0,0 +1,8976 @@ +//=========================================================================== +// 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 +// not use, modify, copy, publish, distribute, disclose or transmit this software +// or the related documents without Intel's prior written permission. This software +// and the related documents are provided as is, with no express or implied +// warranties, other than those that are expressly stated in the License. +//-------------------------------------------------------------------------- + +/** + * + * @file ctl_api.h + * @version v1-r1 + * + */ +#ifndef _CTL_API_H +#define _CTL_API_H +#if defined(__cplusplus) +#pragma once +#endif + +// standard headers +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +// Intel 'ctlApi' common types +#if !defined(__GNUC__) +#pragma region common +#endif +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_MAKE_VERSION +/// @brief Generates generic ::'ctlApi' API versions +#define CTL_MAKE_VERSION( _major, _minor ) (( _major << 16 )|( _minor & 0x0000ffff)) +#endif // CTL_MAKE_VERSION + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_MAJOR_VERSION +/// @brief Extracts ::'ctlApi' API major version +#define CTL_MAJOR_VERSION( _ver ) ( _ver >> 16 ) +#endif // CTL_MAJOR_VERSION + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_MINOR_VERSION +/// @brief Extracts ::'ctlApi' API minor version +#define CTL_MINOR_VERSION( _ver ) ( _ver & 0x0000ffff ) +#endif // CTL_MINOR_VERSION + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_IMPL_MAJOR_VERSION +/// @brief ::'ctlApi' API major version of this implementation +#define CTL_IMPL_MAJOR_VERSION 1 +#endif // CTL_IMPL_MAJOR_VERSION + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_IMPL_MINOR_VERSION +/// @brief ::'ctlApi' API minor version of this implementation +#define CTL_IMPL_MINOR_VERSION 1 +#endif // CTL_IMPL_MINOR_VERSION + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_IMPL_VERSION +/// @brief ::'ctlApi' API version of this implementation +#define CTL_IMPL_VERSION CTL_MAKE_VERSION( CTL_IMPL_MAJOR_VERSION, CTL_IMPL_MINOR_VERSION ) +#endif // CTL_IMPL_VERSION + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_APICALL +#if defined(_WIN32) +/// @brief Calling convention for all API functions +#define CTL_APICALL __cdecl +#else +#define CTL_APICALL +#endif // defined(_WIN32) +#endif // CTL_APICALL + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_APIEXPORT +#if defined(_WIN32) +/// @brief Microsoft-specific dllexport storage-class attribute +#define CTL_APIEXPORT __declspec(dllexport) +#else +#define CTL_APIEXPORT +#endif // defined(_WIN32) +#endif // CTL_APIEXPORT + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_DLLEXPORT +#if defined(_WIN32) +/// @brief Microsoft-specific dllexport storage-class attribute +#define CTL_DLLEXPORT __declspec(dllexport) +#endif // defined(_WIN32) +#endif // CTL_DLLEXPORT + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_DLLEXPORT +#if __GNUC__ >= 4 +/// @brief GCC-specific dllexport storage-class attribute +#define CTL_DLLEXPORT __attribute__ ((visibility ("default"))) +#else +#define CTL_DLLEXPORT +#endif // __GNUC__ >= 4 +#endif // CTL_DLLEXPORT + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_BIT +/// @brief Generic macro for enumerator bit masks +#define CTL_BIT( _i ) ( 1 << _i ) +#endif // CTL_BIT + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Supported initialization flags +typedef uint32_t ctl_init_flags_t; +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; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Version information +typedef uint32_t ctl_version_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Handle of a control API instance +typedef struct _ctl_api_handle_t *ctl_api_handle_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Handle of a device adapter instance +typedef struct _ctl_device_adapter_handle_t *ctl_device_adapter_handle_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Handle of a device temperature sensor +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; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Handle of a device fan +typedef struct _ctl_fan_handle_t *ctl_fan_handle_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Handle of a device memory module +typedef struct _ctl_mem_handle_t *ctl_mem_handle_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Handle of a device engine group +typedef struct _ctl_engine_handle_t *ctl_engine_handle_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Base for all properties types +typedef struct _ctl_base_interface_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + +} ctl_base_interface_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Value type +typedef enum _ctl_property_value_type_t +{ + CTL_PROPERTY_VALUE_TYPE_BOOL = 0, ///< Boolean + CTL_PROPERTY_VALUE_TYPE_FLOAT = 1, ///< Float + CTL_PROPERTY_VALUE_TYPE_INT32 = 2, ///< Int32 + CTL_PROPERTY_VALUE_TYPE_UINT32 = 3, ///< Unsigned Int32 + CTL_PROPERTY_VALUE_TYPE_ENUM = 4, ///< Enum + CTL_PROPERTY_VALUE_TYPE_CUSTOM = 5, ///< Custom argument + CTL_PROPERTY_VALUE_TYPE_MAX + +} ctl_property_value_type_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Property range details, a generic struct to hold min/max/step size +/// information of various feature properties +typedef struct _ctl_property_range_info_t +{ + float min_possible_value; ///< [out] Minimum possible value + float max_possible_value; ///< [out] Maximum possible value + float step_size; ///< [out] Step size possible + float default_value; ///< [out] Default value + +} ctl_property_range_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Property range details of integer type, a generic struct to hold +/// min/max/step size information of various feature properties +typedef struct _ctl_property_range_info_int_t +{ + int32_t min_possible_value; ///< [out] Minimum possible value + int32_t max_possible_value; ///< [out] Maximum possible value + int32_t step_size; ///< [out] Step size possible + int32_t default_value; ///< [out] Default value + +} ctl_property_range_info_int_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Property range details of unsigned integer type, a generic struct to +/// hold min/max/step size information of various feature properties +typedef struct _ctl_property_range_info_uint_t +{ + uint32_t min_possible_value; ///< [out] Minimum possible value + uint32_t max_possible_value; ///< [out] Maximum possible value + uint32_t step_size; ///< [out] Step size possible + uint32_t default_value; ///< [out] Default value + +} ctl_property_range_info_uint_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Bool feature details +typedef struct _ctl_property_info_boolean_t +{ + bool DefaultState; ///< [out] Default state + +} ctl_property_info_boolean_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Bool feature for get/set +typedef struct _ctl_property_boolean_t +{ + bool Enable; ///< [in,out] Enable + +} ctl_property_boolean_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Enumeration feature details +typedef struct _ctl_property_info_enum_t +{ + uint64_t SupportedTypes; ///< [out] Supported possible values represented as a bitmask + uint32_t DefaultType; ///< [out] Default type + +} ctl_property_info_enum_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Enumeration feature for get/set +typedef struct _ctl_property_enum_t +{ + uint32_t EnableType; ///< [in,out] Enable with specific type + +} ctl_property_enum_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Float feature details +typedef struct _ctl_property_info_float_t +{ + bool DefaultEnable; ///< [in,out] DefaultEnable + ctl_property_range_info_t RangeInfo; ///< [out] Min/max/default/step details + +} ctl_property_info_float_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Float feature for get/set +typedef struct _ctl_property_float_t +{ + bool Enable; ///< [in,out] Enable + float Value; ///< [in,out] Value + +} ctl_property_float_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Int32 feature details +typedef struct _ctl_property_info_int_t +{ + bool DefaultEnable; ///< [in,out] DefaultEnable + ctl_property_range_info_int_t RangeInfo; ///< [out] Min/max/default/step details + +} ctl_property_info_int_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Int32 feature for get/set +typedef struct _ctl_property_int_t +{ + bool Enable; ///< [in,out] Enable + int32_t Value; ///< [in,out] Value + +} ctl_property_int_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Int32 feature details +typedef struct _ctl_property_info_uint_t +{ + bool DefaultEnable; ///< [in,out] DefaultEnable + ctl_property_range_info_uint_t RangeInfo; ///< [out] Min/max/default/step details + +} ctl_property_info_uint_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Int32 feature for get/set +typedef struct _ctl_property_uint_t +{ + bool Enable; ///< [in,out] Enable + uint32_t Value; ///< [in,out] Value + +} ctl_property_uint_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Feature element details, union of bool/float/enum property_info +/// structs. Used for feature specific capability check +typedef union _ctl_property_info_t +{ + ctl_property_info_boolean_t BoolType; ///< [in,out] Boolean type fields + ctl_property_info_float_t FloatType; ///< [in,out] Float type fields + ctl_property_info_int_t IntType; ///< [in,out] Int type fields + ctl_property_info_enum_t EnumType; ///< [in,out] Enum type fields + ctl_property_info_uint_t UIntType; ///< [in,out] Unsigned Int type fields + +} ctl_property_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Feature element details, union of bool/float/enum property structs. +/// Used for get/set calls +typedef union _ctl_property_t +{ + ctl_property_boolean_t BoolType; ///< [in,out] Boolean type fields + ctl_property_float_t FloatType; ///< [in,out] Float type fields + ctl_property_int_t IntType; ///< [in,out] Int type fields + ctl_property_enum_t EnumType; ///< [in,out] Enum type fields + ctl_property_uint_t UIntType; ///< [in,out] Unsigned Int type fields + +} ctl_property_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Defines Return/Error codes. +/// All generic error (bit30) codes are between 0x40000000-0x4000FFFF. +/// All 3D (bit 29) specific error codes are between 0x60000000-0x6000FFFF. +/// All media (bit 28) specific error codes are between 0x50000000-0x5000FFFF. +/// All display (bit 27) specific error codes are between 0x48000000-0x4800FFFF +/// All core (bit 26) specific error codes are between 0x44000000-0x4400FFFF +/// Success result code with additional info are between 0x00000001-0x0000FFFF. +typedef enum _ctl_result_t +{ + CTL_RESULT_SUCCESS = 0x00000000, ///< success + CTL_RESULT_SUCCESS_STILL_OPEN_BY_ANOTHER_CALLER = 0x00000001, ///< success but still open by another caller + CTL_RESULT_ERROR_SUCCESS_END = 0x0000FFFF, ///< "Success group error code end value, not to be used + ///< " + CTL_RESULT_ERROR_GENERIC_START = 0x40000000, ///< Generic error code starting value, not to be used + CTL_RESULT_ERROR_NOT_INITIALIZED = 0x40000001, ///< Result not initialized + CTL_RESULT_ERROR_ALREADY_INITIALIZED = 0x40000002, ///< Already initialized + CTL_RESULT_ERROR_DEVICE_LOST = 0x40000003, ///< Device hung, reset, was removed, or driver update occurred + CTL_RESULT_ERROR_OUT_OF_HOST_MEMORY = 0x40000004, ///< Insufficient host memory to satisfy call + CTL_RESULT_ERROR_OUT_OF_DEVICE_MEMORY = 0x40000005, ///< Insufficient device memory to satisfy call + CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS = 0x40000006, ///< Access denied due to permission level + CTL_RESULT_ERROR_NOT_AVAILABLE = 0x40000007, ///< Resource was removed + CTL_RESULT_ERROR_UNINITIALIZED = 0x40000008, ///< Library not initialized + CTL_RESULT_ERROR_UNSUPPORTED_VERSION = 0x40000009, ///< Generic error code for unsupported versions + CTL_RESULT_ERROR_UNSUPPORTED_FEATURE = 0x4000000a, ///< Generic error code for unsupported features + CTL_RESULT_ERROR_INVALID_ARGUMENT = 0x4000000b, ///< Generic error code for invalid arguments + CTL_RESULT_ERROR_INVALID_API_HANDLE = 0x4000000c, ///< API handle in invalid + CTL_RESULT_ERROR_INVALID_NULL_HANDLE = 0x4000000d, ///< Handle argument is not valid + CTL_RESULT_ERROR_INVALID_NULL_POINTER = 0x4000000e, ///< Pointer argument may not be nullptr + CTL_RESULT_ERROR_INVALID_SIZE = 0x4000000f, ///< Size argument is invalid (e.g., must not be zero) + CTL_RESULT_ERROR_UNSUPPORTED_SIZE = 0x40000010, ///< Size argument is not supported by the device (e.g., too large) + CTL_RESULT_ERROR_UNSUPPORTED_IMAGE_FORMAT = 0x40000011, ///< Image format is not supported by the device + CTL_RESULT_ERROR_DATA_READ = 0x40000012, ///< Data read error + CTL_RESULT_ERROR_DATA_WRITE = 0x40000013, ///< Data write error + CTL_RESULT_ERROR_DATA_NOT_FOUND = 0x40000014, ///< Data not found error + CTL_RESULT_ERROR_NOT_IMPLEMENTED = 0x40000015, ///< Function not implemented + CTL_RESULT_ERROR_OS_CALL = 0x40000016, ///< Operating system call failure + CTL_RESULT_ERROR_KMD_CALL = 0x40000017, ///< Kernel mode driver call failure + CTL_RESULT_ERROR_UNLOAD = 0x40000018, ///< Library unload failure + CTL_RESULT_ERROR_ZE_LOADER = 0x40000019, ///< Level0 loader not found + CTL_RESULT_ERROR_INVALID_OPERATION_TYPE = 0x4000001a, ///< Invalid operation type + CTL_RESULT_ERROR_NULL_OS_INTERFACE = 0x4000001b,///< Null OS interface + CTL_RESULT_ERROR_NULL_OS_ADAPATER_HANDLE = 0x4000001c, ///< Null OS adapter handle + CTL_RESULT_ERROR_NULL_OS_DISPLAY_OUTPUT_HANDLE = 0x4000001d,///< Null display output handle + CTL_RESULT_ERROR_WAIT_TIMEOUT = 0x4000001e, ///< Timeout in Wait function + CTL_RESULT_ERROR_PERSISTANCE_NOT_SUPPORTED = 0x4000001f,///< Persistance not supported + CTL_RESULT_ERROR_PLATFORM_NOT_SUPPORTED = 0x40000020, ///< Platform not supported + CTL_RESULT_ERROR_UNKNOWN_APPLICATION_UID = 0x40000021, ///< Unknown Appplicaion UID in Initialization call + CTL_RESULT_ERROR_INVALID_ENUMERATION = 0x40000022, ///< The enum is not valid + CTL_RESULT_ERROR_FILE_DELETE = 0x40000023, ///< Error in file delete operation + CTL_RESULT_ERROR_RESET_DEVICE_REQUIRED = 0x40000024,///< The device requires a reset. + CTL_RESULT_ERROR_FULL_REBOOT_REQUIRED = 0x40000025, ///< The device requires a full reboot. + 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 + CTL_RESULT_ERROR_CORE_OVERCLOCK_NOT_SUPPORTED = 0x44000001, ///< The Overclock is not supported. + 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 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 + CTL_RESULT_ERROR_3D_END = 0x6000FFFF, ///< "3D error code end value, not to be used + ///< " + CTL_RESULT_ERROR_MEDIA_START = 0x50000000, ///< Media error code starting value, not to be used + CTL_RESULT_ERROR_MEDIA_END = 0x5000FFFF, ///< "Media error code end value, not to be used + ///< " + CTL_RESULT_ERROR_DISPLAY_START = 0x48000000, ///< Display error code starting value, not to be used + CTL_RESULT_ERROR_INVALID_AUX_ACCESS_FLAG = 0x48000001, ///< Invalid flag for Aux access + CTL_RESULT_ERROR_INVALID_SHARPNESS_FILTER_FLAG = 0x48000002,///< Invalid flag for Sharpness + CTL_RESULT_ERROR_DISPLAY_NOT_ATTACHED = 0x48000003, ///< Error for Display not attached + CTL_RESULT_ERROR_DISPLAY_NOT_ACTIVE = 0x48000004, ///< Error for display attached but not active + CTL_RESULT_ERROR_INVALID_POWERFEATURE_OPTIMIZATION_FLAG = 0x48000005, ///< Error for invalid power optimization flag + CTL_RESULT_ERROR_INVALID_POWERSOURCE_TYPE_FOR_DPST = 0x48000006,///< DPST is supported only in DC Mode + CTL_RESULT_ERROR_INVALID_PIXTX_GET_CONFIG_QUERY_TYPE = 0x48000007, ///< Invalid query type for pixel transformation get configuration + CTL_RESULT_ERROR_INVALID_PIXTX_SET_CONFIG_OPERATION_TYPE = 0x48000008, ///< Invalid operation type for pixel transformation set configuration + CTL_RESULT_ERROR_INVALID_SET_CONFIG_NUMBER_OF_SAMPLES = 0x48000009, ///< Invalid number of samples for pixel transformation set configuration + CTL_RESULT_ERROR_INVALID_PIXTX_BLOCK_ID = 0x4800000a, ///< Invalid block id for pixel transformation + CTL_RESULT_ERROR_INVALID_PIXTX_BLOCK_TYPE = 0x4800000b, ///< Invalid block type for pixel transformation + CTL_RESULT_ERROR_INVALID_PIXTX_BLOCK_NUMBER = 0x4800000c, ///< Invalid block number for pixel transformation + CTL_RESULT_ERROR_INSUFFICIENT_PIXTX_BLOCK_CONFIG_MEMORY = 0x4800000d, ///< Insufficient memery allocated for BlockConfigs + CTL_RESULT_ERROR_3DLUT_INVALID_PIPE = 0x4800000e, ///< Invalid pipe for 3dlut + CTL_RESULT_ERROR_3DLUT_INVALID_DATA = 0x4800000f, ///< Invalid 3dlut data + CTL_RESULT_ERROR_3DLUT_NOT_SUPPORTED_IN_HDR = 0x48000010, ///< 3dlut not supported in HDR + CTL_RESULT_ERROR_3DLUT_INVALID_OPERATION = 0x48000011, ///< Invalid 3dlut operation + CTL_RESULT_ERROR_3DLUT_UNSUCCESSFUL = 0x48000012, ///< 3dlut call unsuccessful + CTL_RESULT_ERROR_AUX_DEFER = 0x48000013, ///< AUX defer failure + CTL_RESULT_ERROR_AUX_TIMEOUT = 0x48000014, ///< AUX timeout failure + CTL_RESULT_ERROR_AUX_INCOMPLETE_WRITE = 0x48000015, ///< AUX incomplete write failure + CTL_RESULT_ERROR_I2C_AUX_STATUS_UNKNOWN = 0x48000016, ///< I2C/AUX unkonown failure + CTL_RESULT_ERROR_I2C_AUX_UNSUCCESSFUL = 0x48000017, ///< I2C/AUX unsuccessful + CTL_RESULT_ERROR_LACE_INVALID_DATA_ARGUMENT_PASSED = 0x48000018,///< Lace Incorrrect AggressivePercent data or LuxVsAggressive Map data + ///< passed by user + CTL_RESULT_ERROR_EXTERNAL_DISPLAY_ATTACHED = 0x48000019,///< External Display is Attached hence fail the Display Switch + CTL_RESULT_ERROR_CUSTOM_MODE_STANDARD_CUSTOM_MODE_EXISTS = 0x4800001a, ///< Standard custom mode exists + CTL_RESULT_ERROR_CUSTOM_MODE_NON_CUSTOM_MATCHING_MODE_EXISTS = 0x4800001b, ///< Non custom matching mode exists + CTL_RESULT_ERROR_CUSTOM_MODE_INSUFFICIENT_MEMORY = 0x4800001c, ///< Custom mode insufficent memory + CTL_RESULT_ERROR_ADAPTER_ALREADY_LINKED = 0x4800001d, ///< Adapter is already linked + CTL_RESULT_ERROR_ADAPTER_NOT_IDENTICAL = 0x4800001e,///< Adapter is not identical for linking + CTL_RESULT_ERROR_ADAPTER_NOT_SUPPORTED_ON_LDA_SECONDARY = 0x4800001f, ///< Adapter is LDA Secondary, so not supporting requested operation + CTL_RESULT_ERROR_SET_FBC_FEATURE_NOT_SUPPORTED = 0x48000020,///< Set FBC Feature not supported + CTL_RESULT_ERROR_DISPLAY_END = 0x4800FFFF, ///< "Display error code end value, not to be used + ///< " + CTL_RESULT_MAX + +} ctl_result_t; + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_MAX_DEVICE_NAME_LEN +/// @brief Maximum IPC handle size +#define CTL_MAX_DEVICE_NAME_LEN 100 +#endif // CTL_MAX_DEVICE_NAME_LEN + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_MAX_RESERVED_SIZE +/// @brief Maximum reserved size for future members. +#define CTL_MAX_RESERVED_SIZE 108 +#endif // CTL_MAX_RESERVED_SIZE + +/////////////////////////////////////////////////////////////////////////////// +/// @brief General Physical Units. +typedef enum _ctl_units_t +{ + CTL_UNITS_FREQUENCY_MHZ = 0, ///< Type is Frequency with units in MHz. + CTL_UNITS_OPERATIONS_GTS = 1, ///< Type is Frequency with units in GT/s (gigatransfers per second). + CTL_UNITS_OPERATIONS_MTS = 2, ///< Type is Frequency with units in MT/s (megatransfers per second). + CTL_UNITS_VOLTAGE_VOLTS = 3, ///< Type is Voltage with units in Volts. + CTL_UNITS_POWER_WATTS = 4, ///< Type is Power with units in Watts. + CTL_UNITS_TEMPERATURE_CELSIUS = 5, ///< Type is Temperature with units in Celsius. + CTL_UNITS_ENERGY_JOULES = 6, ///< Type is Energy with units in Joules. + CTL_UNITS_TIME_SECONDS = 7, ///< Type is Time with units in Seconds. + CTL_UNITS_MEMORY_BYTES = 8, ///< Type is Memory with units in Bytes. + 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 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 + +} ctl_units_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief General Data Types. +typedef enum _ctl_data_type_t +{ + CTL_DATA_TYPE_INT8 = 0, ///< The data type is 8 bit signed integer. + CTL_DATA_TYPE_UINT8 = 1, ///< The data type is 8 bit unsigned integer. + CTL_DATA_TYPE_INT16 = 2, ///< The data type is 16 bit signed integer. + CTL_DATA_TYPE_UINT16 = 3, ///< The data type is 16 bit unsigned integer. + CTL_DATA_TYPE_INT32 = 4, ///< The data type is 32 bit signed integer. + CTL_DATA_TYPE_UINT32 = 5, ///< The data type is 32 bit unsigned integer. + CTL_DATA_TYPE_INT64 = 6, ///< The data type is 64 bit signed integer. + CTL_DATA_TYPE_UINT64 = 7, ///< The data type is 64 bit unsigned integer. + CTL_DATA_TYPE_FLOAT = 8, ///< The data type is 32 bit floating point. + CTL_DATA_TYPE_DOUBLE = 9, ///< The data type is 64 bit floating point. + CTL_DATA_TYPE_STRING_ASCII = 10, ///< The data type is an array of 8 bit unsigned integers. + CTL_DATA_TYPE_STRING_UTF16 = 11, ///< The data type is an array of 16 bit unsigned integers. + CTL_DATA_TYPE_STRING_UTF132 = 12, ///< The data type is an array of 32 bit unsigned integers. + CTL_DATA_TYPE_UNKNOWN = 0x4800FFFF, ///< The data type is unknown. + CTL_DATA_TYPE_MAX + +} ctl_data_type_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Union for Generic Data. +/// +/// @details +/// - The telemetry data items could be of different types. +/// - Refer to ::ctl_data_type_t to find the current type. +typedef union _ctl_data_value_t +{ + int8_t data8; ///< [out] The data type is 8 bit signed integer. + uint8_t datau8; ///< [out] The data type is 8 bit unsigned integer. + int16_t data16; ///< [out] The data type is 16 bit signed integer. + uint16_t datau16; ///< [out] The data type is 16 bit unsigned integer. + int32_t data32; ///< [out] The data type is 32 bit signed integer. + uint32_t datau32; ///< [out] The data type is 32 bit unsigned integer. + int64_t data64; ///< [out] The data type is 64 bit signed integer. + uint64_t datau64; ///< [out] The data type is 64 bit unsigned integer. + float datafloat; ///< [out] The data type is 32 bit floating point. + double datadouble; ///< [out] The data type is 64 bit floating point. + +} ctl_data_value_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Base for all properties types +typedef struct _ctl_base_properties_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + +} ctl_base_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Application Unique ID +typedef struct _ctl_application_id_t +{ + uint32_t Data1; ///< [in] Data1 + uint16_t Data2; ///< [in] Data2 + uint16_t Data3; ///< [in] Data3 + uint8_t Data4[8]; ///< [in] Data4 + +} ctl_application_id_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Init arguments +typedef struct _ctl_init_args_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_version_info_t AppVersion; ///< [in][release] App's IGCL version + ctl_init_flags_t flags; ///< [in][release] Caller version + ctl_version_info_t SupportedVersion; ///< [out][release] IGCL implementation version + ctl_application_id_t ApplicationUID; ///< [in] Application Provided Unique ID.Application can pass all 0's as + ///< the default ID + +} ctl_init_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Reserved struct +typedef struct _ctl_reserved_args_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + void* pSpecialArg; ///< [in] Reserved struct + uint32_t ArgSize; ///< [in] struct size + +} ctl_reserved_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Reserved base struct +typedef struct _ctl_reserved_args_base_t +{ + ctl_application_id_t ReservedFuncID; ///< [in] Unique ID for reserved/special function + +} ctl_reserved_args_base_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Reserved - Unlock function capability +typedef struct _ctl_unlock_capability_t +{ + ctl_application_id_t ReservedFuncID; ///< [in] Unique ID for reserved/special function + ctl_application_id_t UnlockCapsID; ///< [in] Unique ID to unlock a specific function + +} ctl_unlock_capability_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Used by loader like modules to specify runtime implementation details +typedef struct _ctl_runtime_path_args_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_application_id_t UnlockID; ///< [in] Unique ID for reserved/special function + wchar_t* pRuntimePath; ///< [in] Path to runtime DLL + uint16_t DeviceID; ///< [in] Device ID of interest to caller. pRuntimePath should not be NULL. + uint8_t RevID; ///< [in] Revision ID of interest to caller. pRuntimePath should not be + ///< NULL. + +} ctl_runtime_path_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Control Api Init +/// +/// @details +/// - Control Api Init +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pInitDesc` +/// + `nullptr == phAPIHandle` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlInit( + ctl_init_args_t* pInitDesc, ///< [in][out] App's control API version + ctl_api_handle_t* phAPIHandle ///< [in][out][release] Control API handle + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Control Api Destroy +/// +/// @details +/// - Control Api Close +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hAPIHandle` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlClose( + ctl_api_handle_t hAPIHandle ///< [in][release] Control API implementation handle obtained during init + ///< call + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Runtime path +/// +/// @details +/// - Control Api set runtime path. Optional call from a loader which allows +/// the loaded runtime to enumerate only the adapters which the specified +/// runtime is responsible for. This is done usually by a loader or by +/// callers who know how to get the specific runtime of interest. This +/// call right now is reserved for use by Intel components. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pArgs` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlSetRuntimePath( + ctl_runtime_path_args_t* pArgs ///< [in] Runtime path + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Supported Functions +typedef uint32_t ctl_supported_functions_flags_t; +typedef enum _ctl_supported_functions_flag_t +{ + CTL_SUPPORTED_FUNCTIONS_FLAG_DISPLAY = CTL_BIT(0), ///< [out] Is Display supported + CTL_SUPPORTED_FUNCTIONS_FLAG_3D = CTL_BIT(1), ///< [out] Is 3D supported + CTL_SUPPORTED_FUNCTIONS_FLAG_MEDIA = CTL_BIT(2),///< [out] Is Media supported + CTL_SUPPORTED_FUNCTIONS_FLAG_MAX = 0x80000000 + +} ctl_supported_functions_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Firmware version +typedef struct _ctl_firmware_version_t +{ + uint64_t major_version; ///< [out] Major version + uint64_t minor_version; ///< [out] Minor version + uint64_t build_number; ///< [out] Build number + +} ctl_firmware_version_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief DeviceType +typedef enum _ctl_device_type_t +{ + CTL_DEVICE_TYPE_GRAPHICS = 1, ///< Graphics Device type + CTL_DEVICE_TYPE_SYSTEM = 2, ///< System Device type + CTL_DEVICE_TYPE_MAX + +} ctl_device_type_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Adapter Properties +typedef uint32_t ctl_adapter_properties_flags_t; +typedef enum _ctl_adapter_properties_flag_t +{ + CTL_ADAPTER_PROPERTIES_FLAG_INTEGRATED = CTL_BIT(0),///< [out] Is Integrated Graphics adapter + CTL_ADAPTER_PROPERTIES_FLAG_LDA_PRIMARY = CTL_BIT(1), ///< [out] Is Primary (Lead) adapter in a Linked Display Adapter (LDA) + ///< chain + CTL_ADAPTER_PROPERTIES_FLAG_LDA_SECONDARY = CTL_BIT(2), ///< [out] Is Secondary (Linked) adapter in a Linked Display Adapter (LDA) + ///< chain + CTL_ADAPTER_PROPERTIES_FLAG_MAX = 0x80000000 + +} ctl_adapter_properties_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Adapter Pci Bus, Device, Function +typedef struct _ctl_adapter_bdf_t +{ + uint8_t bus; ///< [out] PCI Bus Number + uint8_t device; ///< [out] PCI device number + uint8_t function; ///< [out] PCI function + +} ctl_adapter_bdf_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Device Adapter properties +typedef struct _ctl_device_adapter_properties_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + void* pDeviceID; ///< [in,out] OS specific Device ID + uint32_t device_id_size; ///< [in] size of the device ID + 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] 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 + uint32_t num_eus_per_sub_slice; ///< [out] Number of EUs per sub-slice + uint32_t num_sub_slices_per_slice; ///< [out] Number of sub-slices per slice + 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] 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; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief OperationType +typedef enum _ctl_operation_type_t +{ + CTL_OPERATION_TYPE_READ = 1, ///< Read operation + CTL_OPERATION_TYPE_WRITE = 2, ///< Write operation + CTL_OPERATION_TYPE_MAX + +} ctl_operation_type_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Generic Structure for Void* datatypes +typedef struct _ctl_generic_void_datatype_t +{ + void* pData; ///< [in,out]void pointer to memory + uint32_t size; ///< [in,out]size of the allocated memory + +} ctl_generic_void_datatype_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Generic Structure for Revision datatypes +typedef struct _ctl_revision_datatype_t +{ + uint8_t major_version; ///< [in,out]Major Version + uint8_t minor_version; ///< [in,out]Minor Version + uint8_t revision_version; ///< [in,out]Revision Version + +} ctl_revision_datatype_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Property Type flags +typedef uint32_t ctl_property_type_flags_t; +typedef enum _ctl_property_type_flag_t +{ + CTL_PROPERTY_TYPE_FLAG_DISPLAY = CTL_BIT(0), ///< Display type. Supported scenarios: Sharpness/gamma/CSC + CTL_PROPERTY_TYPE_FLAG_3D = CTL_BIT(1), ///< 3D type. Supported scenarios: All set calls via IGCL's 3D APIs + CTL_PROPERTY_TYPE_FLAG_MEDIA = CTL_BIT(2), ///< Media type. Supported scenarios: All set calls via IGCL's media APIs + CTL_PROPERTY_TYPE_FLAG_CORE = CTL_BIT(3), ///< For future: Core graphic event types like clocking, frequency etc. + CTL_PROPERTY_TYPE_FLAG_MAX = 0x80000000 + +} ctl_property_type_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Arguments related to wait for a property change function +typedef struct _ctl_wait_property_change_args_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_property_type_flags_t PropertyType; ///< [in] Type of the property + uint32_t TimeOutMilliSec; ///< [in][release] Time-out interval in milliseconds. Specify 0xFFFFFFFF if + ///< time-out is not desired + uint32_t EventMiscFlags; ///< [in][release] Event flags for future use + void* pReserved; ///< [in][release] Reserved for future use + uint64_t ReservedOutFlags; ///< [out] Reserved out argument for future use + +} ctl_wait_property_change_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Display orientation (rotation) +typedef enum _ctl_display_orientation_t +{ + CTL_DISPLAY_ORIENTATION_0 = 0, ///< 0 Degree + CTL_DISPLAY_ORIENTATION_90 = 1, ///< 90 Degree + CTL_DISPLAY_ORIENTATION_180 = 2, ///< 180 Degree + CTL_DISPLAY_ORIENTATION_270 = 3, ///< 270 Degree + CTL_DISPLAY_ORIENTATION_MAX + +} ctl_display_orientation_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Rectangle +typedef struct _ctl_rect_t +{ + int32_t Left; ///< [in,out] Left + int32_t Top; ///< [in,out] Top + int32_t Right; ///< [in,out] Right + int32_t Bottom; ///< [in,out] Bottom + +} ctl_rect_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Wait for a property change. Note that this is a blocking call +/// +/// @details +/// - Wait for a property change in display, 3d, media etc. +/// +/// @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 == pArgs` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlWaitForPropertyChange( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter + ctl_wait_property_change_args_t* pArgs ///< [in] Argument containing information about which property changes to + ///< listen for + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Reserved function +/// +/// @details +/// - Reserved function +/// +/// @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 == pArgs` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlReservedCall( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter + ctl_reserved_args_t* pArgs ///< [in] Argument containing information + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_base_interface_t +typedef struct _ctl_base_interface_t ctl_base_interface_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_property_range_info_t +typedef struct _ctl_property_range_info_t ctl_property_range_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_property_range_info_int_t +typedef struct _ctl_property_range_info_int_t ctl_property_range_info_int_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_property_range_info_uint_t +typedef struct _ctl_property_range_info_uint_t ctl_property_range_info_uint_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_property_info_boolean_t +typedef struct _ctl_property_info_boolean_t ctl_property_info_boolean_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_property_boolean_t +typedef struct _ctl_property_boolean_t ctl_property_boolean_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_property_info_enum_t +typedef struct _ctl_property_info_enum_t ctl_property_info_enum_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_property_enum_t +typedef struct _ctl_property_enum_t ctl_property_enum_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_property_info_float_t +typedef struct _ctl_property_info_float_t ctl_property_info_float_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_property_float_t +typedef struct _ctl_property_float_t ctl_property_float_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_property_info_int_t +typedef struct _ctl_property_info_int_t ctl_property_info_int_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_property_int_t +typedef struct _ctl_property_int_t ctl_property_int_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_property_info_uint_t +typedef struct _ctl_property_info_uint_t ctl_property_info_uint_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_property_uint_t +typedef struct _ctl_property_uint_t ctl_property_uint_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_base_properties_t +typedef struct _ctl_base_properties_t ctl_base_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_application_id_t +typedef struct _ctl_application_id_t ctl_application_id_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_init_args_t +typedef struct _ctl_init_args_t ctl_init_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_reserved_args_t +typedef struct _ctl_reserved_args_t ctl_reserved_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_reserved_args_base_t +typedef struct _ctl_reserved_args_base_t ctl_reserved_args_base_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_unlock_capability_t +typedef struct _ctl_unlock_capability_t ctl_unlock_capability_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_runtime_path_args_t +typedef struct _ctl_runtime_path_args_t ctl_runtime_path_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_firmware_version_t +typedef struct _ctl_firmware_version_t ctl_firmware_version_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_adapter_bdf_t +typedef struct _ctl_adapter_bdf_t ctl_adapter_bdf_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_device_adapter_properties_t +typedef struct _ctl_device_adapter_properties_t ctl_device_adapter_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_generic_void_datatype_t +typedef struct _ctl_generic_void_datatype_t ctl_generic_void_datatype_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_revision_datatype_t +typedef struct _ctl_revision_datatype_t ctl_revision_datatype_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_wait_property_change_args_t +typedef struct _ctl_wait_property_change_args_t ctl_wait_property_change_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_rect_t +typedef struct _ctl_rect_t ctl_rect_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_endurance_gaming_caps_t +typedef struct _ctl_endurance_gaming_caps_t ctl_endurance_gaming_caps_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_endurance_gaming_t +typedef struct _ctl_endurance_gaming_t ctl_endurance_gaming_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_endurance_gaming2_t +typedef struct _ctl_endurance_gaming2_t ctl_endurance_gaming2_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_adaptivesync_caps_t +typedef struct _ctl_adaptivesync_caps_t ctl_adaptivesync_caps_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_adaptivesync_getset_t +typedef struct _ctl_adaptivesync_getset_t ctl_adaptivesync_getset_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_3d_app_profiles_caps_t +typedef struct _ctl_3d_app_profiles_caps_t ctl_3d_app_profiles_caps_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_3d_app_profiles_t +typedef struct _ctl_3d_app_profiles_t ctl_3d_app_profiles_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_3d_tier_details_t +typedef struct _ctl_3d_tier_details_t ctl_3d_tier_details_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_3d_feature_details_t +typedef struct _ctl_3d_feature_details_t ctl_3d_feature_details_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_3d_feature_caps_t +typedef struct _ctl_3d_feature_caps_t ctl_3d_feature_caps_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_3d_feature_getset_t +typedef struct _ctl_3d_feature_getset_t ctl_3d_feature_getset_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_kmd_load_features_t +typedef struct _ctl_kmd_load_features_t ctl_kmd_load_features_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_display_timing_t +typedef struct _ctl_display_timing_t ctl_display_timing_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_display_properties_t +typedef struct _ctl_display_properties_t ctl_display_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_adapter_display_encoder_properties_t +typedef struct _ctl_adapter_display_encoder_properties_t ctl_adapter_display_encoder_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_sharpness_filter_properties_t +typedef struct _ctl_sharpness_filter_properties_t ctl_sharpness_filter_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_sharpness_caps_t +typedef struct _ctl_sharpness_caps_t ctl_sharpness_caps_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_sharpness_settings_t +typedef struct _ctl_sharpness_settings_t ctl_sharpness_settings_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_i2c_access_args_t +typedef struct _ctl_i2c_access_args_t ctl_i2c_access_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_i2c_access_pinpair_args_t +typedef struct _ctl_i2c_access_pinpair_args_t ctl_i2c_access_pinpair_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_aux_access_args_t +typedef struct _ctl_aux_access_args_t ctl_aux_access_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_power_optimization_caps_t +typedef struct _ctl_power_optimization_caps_t ctl_power_optimization_caps_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_power_optimization_lrr_t +typedef struct _ctl_power_optimization_lrr_t ctl_power_optimization_lrr_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_power_optimization_psr_t +typedef struct _ctl_power_optimization_psr_t ctl_power_optimization_psr_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_power_optimization_dpst_t +typedef struct _ctl_power_optimization_dpst_t ctl_power_optimization_dpst_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_power_optimization_settings_t +typedef struct _ctl_power_optimization_settings_t ctl_power_optimization_settings_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_set_brightness_t +typedef struct _ctl_set_brightness_t ctl_set_brightness_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_get_brightness_t +typedef struct _ctl_get_brightness_t ctl_get_brightness_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_pixtx_color_primaries_t +typedef struct _ctl_pixtx_color_primaries_t ctl_pixtx_color_primaries_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_pixtx_pixel_format_t +typedef struct _ctl_pixtx_pixel_format_t ctl_pixtx_pixel_format_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_pixtx_1dlut_config_t +typedef struct _ctl_pixtx_1dlut_config_t ctl_pixtx_1dlut_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_pixtx_matrix_config_t +typedef struct _ctl_pixtx_matrix_config_t ctl_pixtx_matrix_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_pixtx_3dlut_sample_t +typedef struct _ctl_pixtx_3dlut_sample_t ctl_pixtx_3dlut_sample_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_pixtx_3dlut_config_t +typedef struct _ctl_pixtx_3dlut_config_t ctl_pixtx_3dlut_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_pixtx_block_config_t +typedef struct _ctl_pixtx_block_config_t ctl_pixtx_block_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_pixtx_pipe_get_config_t +typedef struct _ctl_pixtx_pipe_get_config_t ctl_pixtx_pipe_get_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_pixtx_pipe_set_config_t +typedef struct _ctl_pixtx_pipe_set_config_t ctl_pixtx_pipe_set_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_panel_descriptor_access_args_t +typedef struct _ctl_panel_descriptor_access_args_t ctl_panel_descriptor_access_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_retro_scaling_settings_t +typedef struct _ctl_retro_scaling_settings_t ctl_retro_scaling_settings_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_retro_scaling_caps_t +typedef struct _ctl_retro_scaling_caps_t ctl_retro_scaling_caps_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_scaling_caps_t +typedef struct _ctl_scaling_caps_t ctl_scaling_caps_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_scaling_settings_t +typedef struct _ctl_scaling_settings_t ctl_scaling_settings_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_lace_lux_aggr_map_entry_t +typedef struct _ctl_lace_lux_aggr_map_entry_t ctl_lace_lux_aggr_map_entry_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_lace_lux_aggr_map_t +typedef struct _ctl_lace_lux_aggr_map_t ctl_lace_lux_aggr_map_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_lace_config_t +typedef struct _ctl_lace_config_t ctl_lace_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_sw_psr_settings_t +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_intel_arc_sync_profile_params_t +typedef struct _ctl_intel_arc_sync_profile_params_t ctl_intel_arc_sync_profile_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_edid_management_args_t +typedef struct _ctl_edid_management_args_t ctl_edid_management_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_get_set_custom_mode_args_t +typedef struct _ctl_get_set_custom_mode_args_t ctl_get_set_custom_mode_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_custom_src_mode_t +typedef struct _ctl_custom_src_mode_t ctl_custom_src_mode_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_child_display_target_mode_t +typedef struct _ctl_child_display_target_mode_t ctl_child_display_target_mode_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_combined_display_child_info_t +typedef struct _ctl_combined_display_child_info_t ctl_combined_display_child_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_combined_display_args_t +typedef struct _ctl_combined_display_args_t ctl_combined_display_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_genlock_display_info_t +typedef struct _ctl_genlock_display_info_t ctl_genlock_display_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_genlock_target_mode_list_t +typedef struct _ctl_genlock_target_mode_list_t ctl_genlock_target_mode_list_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_genlock_topology_t +typedef struct _ctl_genlock_topology_t ctl_genlock_topology_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_genlock_args_t +typedef struct _ctl_genlock_args_t ctl_genlock_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_vblank_ts_args_t +typedef struct _ctl_vblank_ts_args_t ctl_vblank_ts_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_lda_args_t +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; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_engine_stats_t +typedef struct _ctl_engine_stats_t ctl_engine_stats_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_fan_speed_t +typedef struct _ctl_fan_speed_t ctl_fan_speed_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_fan_temp_speed_t +typedef struct _ctl_fan_temp_speed_t ctl_fan_temp_speed_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_fan_speed_table_t +typedef struct _ctl_fan_speed_table_t ctl_fan_speed_table_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_fan_properties_t +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; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_freq_range_t +typedef struct _ctl_freq_range_t ctl_freq_range_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_freq_state_t +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; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_video_processing_super_resolution_t +typedef struct _ctl_video_processing_super_resolution_t ctl_video_processing_super_resolution_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_video_processing_noise_reduction_info_t +typedef struct _ctl_video_processing_noise_reduction_info_t ctl_video_processing_noise_reduction_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_video_processing_noise_reduction_t +typedef struct _ctl_video_processing_noise_reduction_t ctl_video_processing_noise_reduction_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_video_processing_adaptive_contrast_enhancement_info_t +typedef struct _ctl_video_processing_adaptive_contrast_enhancement_info_t ctl_video_processing_adaptive_contrast_enhancement_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_video_processing_adaptive_contrast_enhancement_t +typedef struct _ctl_video_processing_adaptive_contrast_enhancement_t ctl_video_processing_adaptive_contrast_enhancement_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_video_processing_standard_color_correction_info_t +typedef struct _ctl_video_processing_standard_color_correction_info_t ctl_video_processing_standard_color_correction_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_video_processing_standard_color_correction_t +typedef struct _ctl_video_processing_standard_color_correction_t ctl_video_processing_standard_color_correction_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_video_processing_total_color_correction_info_t +typedef struct _ctl_video_processing_total_color_correction_info_t ctl_video_processing_total_color_correction_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_video_processing_total_color_correction_t +typedef struct _ctl_video_processing_total_color_correction_t ctl_video_processing_total_color_correction_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_video_processing_feature_details_t +typedef struct _ctl_video_processing_feature_details_t ctl_video_processing_feature_details_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_video_processing_feature_caps_t +typedef struct _ctl_video_processing_feature_caps_t ctl_video_processing_feature_caps_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_video_processing_feature_getset_t +typedef struct _ctl_video_processing_feature_getset_t ctl_video_processing_feature_getset_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_mem_properties_t +typedef struct _ctl_mem_properties_t ctl_mem_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_mem_state_t +typedef struct _ctl_mem_state_t ctl_mem_state_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_mem_bandwidth_t +typedef struct _ctl_mem_bandwidth_t ctl_mem_bandwidth_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_oc_telemetry_item_t +typedef struct _ctl_oc_telemetry_item_t ctl_oc_telemetry_item_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_oc_control_info_t +typedef struct _ctl_oc_control_info_t ctl_oc_control_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_oc_properties_t +typedef struct _ctl_oc_properties_t ctl_oc_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_oc_vf_pair_t +typedef struct _ctl_oc_vf_pair_t ctl_oc_vf_pair_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_psu_info_t +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; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_pci_speed_t +typedef struct _ctl_pci_speed_t ctl_pci_speed_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_pci_properties_t +typedef struct _ctl_pci_properties_t ctl_pci_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_pci_state_t +typedef struct _ctl_pci_state_t ctl_pci_state_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_power_properties_t +typedef struct _ctl_power_properties_t ctl_power_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_power_energy_counter_t +typedef struct _ctl_power_energy_counter_t ctl_power_energy_counter_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_power_sustained_limit_t +typedef struct _ctl_power_sustained_limit_t ctl_power_sustained_limit_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_power_burst_limit_t +typedef struct _ctl_power_burst_limit_t ctl_power_burst_limit_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_power_peak_limit_t +typedef struct _ctl_power_peak_limit_t ctl_power_peak_limit_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_power_limits_t +typedef struct _ctl_power_limits_t ctl_power_limits_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_energy_threshold_t +typedef struct _ctl_energy_threshold_t ctl_energy_threshold_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Forward-declare ctl_temp_properties_t +typedef struct _ctl_temp_properties_t ctl_temp_properties_t; + + + +#if !defined(__GNUC__) +#pragma endregion // common +#endif +// Intel 'ctlApi' for Device Adapter +#if !defined(__GNUC__) +#pragma region _3D +#endif +/////////////////////////////////////////////////////////////////////////////// +/// @brief Feature type +typedef enum _ctl_3d_feature_t +{ + CTL_3D_FEATURE_FRAME_PACING = 0, ///< Frame pacing. Contains generic enum type fields + CTL_3D_FEATURE_ENDURANCE_GAMING = 1, ///< Endurance gaming. Contains generic integer type fields. Value will be + ///< interpreted as the max FPS to be used when in DC mode globally or per + ///< application + CTL_3D_FEATURE_FRAME_LIMIT = 2, ///< Frame limit for games. Contains generic integer type fields. Value + ///< will be interpreted as the max FPS to be used independent of system + ///< power state + CTL_3D_FEATURE_ANISOTROPIC = 3, ///< ANISOTROPIC. Contains generic enum type fields + CTL_3D_FEATURE_CMAA = 4, ///< CMAA. Contains generic enum type fields + CTL_3D_FEATURE_TEXTURE_FILTERING_QUALITY = 5, ///< Texture filtering quality. Contains generic enum type fields + CTL_3D_FEATURE_ADAPTIVE_TESSELLATION = 6, ///< Adaptive tessellation quality. Contains generic integer type fields + CTL_3D_FEATURE_SHARPENING_FILTER = 7, ///< Sharpening Filter. Contains generic integer type fields + CTL_3D_FEATURE_MSAA = 8, ///< Msaa. Contains generic enum type fields + CTL_3D_FEATURE_GAMING_FLIP_MODES = 9, ///< Various Gaming flip modes like speed frame, smooth sync & force async + ///< flip. Contains generic enum type fields + CTL_3D_FEATURE_ADAPTIVE_SYNC_PLUS = 10, ///< Adaptive sync plus. Refer custom field ::ctl_adaptivesync_caps_t & + ///< ::ctl_adaptivesync_getset_t + CTL_3D_FEATURE_APP_PROFILES = 11, ///< Game Compatibility & Performance Profiles. Refer custom field + ///< ::ctl_3d_app_profiles_caps_t & ::ctl_3d_app_profiles_t + CTL_3D_FEATURE_APP_PROFILE_DETAILS = 12, ///< Game Profile Customization. Refer custom field ::ctl_3d_tier_details_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; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief 3D feature misc flags +typedef uint32_t ctl_3d_feature_misc_flags_t; +typedef enum _ctl_3d_feature_misc_flag_t +{ + 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; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Anisotropic values possible +typedef enum _ctl_3d_anisotropic_types_t +{ + CTL_3D_ANISOTROPIC_TYPES_APP_CHOICE = 0, ///< Application choice + CTL_3D_ANISOTROPIC_TYPES_2X = 2, ///< 2X + CTL_3D_ANISOTROPIC_TYPES_4X = 4, ///< 4X + CTL_3D_ANISOTROPIC_TYPES_8X = 8, ///< 8X + CTL_3D_ANISOTROPIC_TYPES_16X = 16, ///< 16X + CTL_3D_ANISOTROPIC_TYPES_MAX + +} ctl_3d_anisotropic_types_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Texture filtering values possible +typedef enum _ctl_3d_texture_filtering_quality_types_t +{ + CTL_3D_TEXTURE_FILTERING_QUALITY_TYPES_PERFORMANCE = 0, ///< Performance + CTL_3D_TEXTURE_FILTERING_QUALITY_TYPES_BALANCED = 1,///< Balanced + CTL_3D_TEXTURE_FILTERING_QUALITY_TYPES_QUALITY = 2, ///< Quality + CTL_3D_TEXTURE_FILTERING_QUALITY_TYPES_MAX + +} ctl_3d_texture_filtering_quality_types_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Frame pacing values possible +typedef enum _ctl_3d_frame_pacing_types_t +{ + CTL_3D_FRAME_PACING_TYPES_DISABLE = 0, ///< Disable + CTL_3D_FRAME_PACING_TYPES_ENABLE_MODE_FRAME_NO_SMOOTHENING = 1, ///< Enable with scheduler without any frame smoothening + CTL_3D_FRAME_PACING_TYPES_ENABLE_MODE_FRAME_MAX_SMOOTHENING = 2,///< Enable with scheduler with maximum smoothness + CTL_3D_FRAME_PACING_TYPES_ENABLE_MODE_COMPETITIVE_GAMING = 3, ///< Enable with scheduler in competitive gaming mode + CTL_3D_FRAME_PACING_TYPES_MAX + +} ctl_3d_frame_pacing_types_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Endurance Gaming control possible +typedef enum _ctl_3d_endurance_gaming_control_t +{ + CTL_3D_ENDURANCE_GAMING_CONTROL_TURN_OFF = 0, ///< Endurance Gaming disable + CTL_3D_ENDURANCE_GAMING_CONTROL_TURN_ON = 1, ///< Endurance Gaming enable + CTL_3D_ENDURANCE_GAMING_CONTROL_AUTO = 2, ///< Endurance Gaming auto + CTL_3D_ENDURANCE_GAMING_CONTROL_MAX + +} ctl_3d_endurance_gaming_control_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Endurance Gaming modes possible +typedef enum _ctl_3d_endurance_gaming_mode_t +{ + CTL_3D_ENDURANCE_GAMING_MODE_BETTER_PERFORMANCE = 0,///< Endurance Gaming better performance mode + CTL_3D_ENDURANCE_GAMING_MODE_BALANCED = 1, ///< Endurance Gaming balanced mode + CTL_3D_ENDURANCE_GAMING_MODE_MAXIMUM_BATTERY = 2, ///< Endurance Gaming maximum battery mode + CTL_3D_ENDURANCE_GAMING_MODE_MAX + +} 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 +{ + CTL_3D_CMAA_TYPES_TURN_OFF = 0, ///< Turn off + CTL_3D_CMAA_TYPES_OVERRIDE_MSAA = 1, ///< Override MSAA + CTL_3D_CMAA_TYPES_ENHANCE_APPLICATION = 2, ///< Enhance Application + CTL_3D_CMAA_TYPES_MAX + +} ctl_3d_cmaa_types_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Adaptive Tessellation +typedef enum _ctl_3d_adaptive_tessellation_types_t +{ + CTL_3D_ADAPTIVE_TESSELLATION_TYPES_TURN_OFF = 0,///< Turn off + CTL_3D_ADAPTIVE_TESSELLATION_TYPES_TURN_ON = 1, ///< Turn on + CTL_3D_ADAPTIVE_TESSELLATION_TYPES_MAX + +} ctl_3d_adaptive_tessellation_types_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Sharpening filter values possible +typedef enum _ctl_3d_sharpening_filter_types_t +{ + CTL_3D_SHARPENING_FILTER_TYPES_TURN_OFF = 0, ///< Turn off + CTL_3D_SHARPENING_FILTER_TYPES_TURN_ON = 1, ///< Turn on + CTL_3D_SHARPENING_FILTER_TYPES_MAX + +} ctl_3d_sharpening_filter_types_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief MSAA values possible +typedef enum _ctl_3d_msaa_types_t +{ + CTL_3D_MSAA_TYPES_APP_CHOICE = 0, ///< Application choice + CTL_3D_MSAA_TYPES_DISABLED = 1, ///< Disabled. MSAA count 1 + CTL_3D_MSAA_TYPES_2X = 2, ///< 2X + CTL_3D_MSAA_TYPES_4X = 4, ///< 4X + CTL_3D_MSAA_TYPES_8X = 8, ///< 8X + CTL_3D_MSAA_TYPES_16X = 16, ///< 16X + CTL_3D_MSAA_TYPES_MAX + +} ctl_3d_msaa_types_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Gaming flip modes +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 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; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Endurance Gaming caps +typedef struct _ctl_endurance_gaming_caps_t +{ + ctl_property_info_enum_t EGControlCaps; ///< [out] Endurance Gaming control capability + ctl_property_info_enum_t EGModeCaps; ///< [out] Endurance Gaming mode capability + +} ctl_endurance_gaming_caps_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Endurance Gaming Get/Set +typedef struct _ctl_endurance_gaming_t +{ + ctl_3d_endurance_gaming_control_t EGControl; ///< [in,out] Endurance Gaming control - Off/On/Auto + ctl_3d_endurance_gaming_mode_t EGMode; ///< [in,out] Endurance Gaming mode - Better Performance/Balanced/Maximum + ///< Battery + +} ctl_endurance_gaming_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Endurance Gaming version2 Get/Set +typedef struct _ctl_endurance_gaming2_t +{ + ctl_3d_endurance_gaming_control_t EGControl; ///< [in,out] Endurance Gaming control - Off/On/Auto + ctl_3d_endurance_gaming_mode_t EGMode; ///< [in,out] Endurance Gaming mode - Better Performance/Balanced/Maximum + ///< Battery + bool IsFPRequired; ///< [out] Is frame pacing required, dynamic state + double TargetFPS; ///< [out] Target FPS for frame pacing + double RefreshRate; ///< [out] Refresh rate used to calculate target fps + uint32_t Reserved[4]; ///< [out] Reserved fields + +} ctl_endurance_gaming2_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Adaptive sync plus caps +typedef struct _ctl_adaptivesync_caps_t +{ + bool AdaptiveBalanceSupported; ///< [out] Adaptive balance supported + ctl_property_info_float_t AdaptiveBalanceStrengthCaps; ///< [out] Strength of adaptive balance algorithm - min/max/steps/default + +} ctl_adaptivesync_caps_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Adaptive sync plus +typedef struct _ctl_adaptivesync_getset_t +{ + bool AdaptiveSync; ///< [in,out] Adaptive sync. Note that in Windows, OS controls state of + ///< adaptive sync and which game gets the feature using it's own policies + bool AdaptiveBalance; ///< [in,out] Adaptive balance + bool AllowAsyncForHighFPS; ///< [in,out] Allow async flips when FPS is higher than max refresh rate of + ///< the panel + float AdaptiveBalanceStrength; ///< [in,out] Adaptive balance strength + +} ctl_adaptivesync_getset_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Game tier types +typedef uint32_t ctl_3d_tier_type_flags_t; +typedef enum _ctl_3d_tier_type_flag_t +{ + CTL_3D_TIER_TYPE_FLAG_COMPATIBILITY = CTL_BIT(0), ///< Compatibility Tier + CTL_3D_TIER_TYPE_FLAG_PERFORMANCE = CTL_BIT(1), ///< Performance Tier + CTL_3D_TIER_TYPE_FLAG_MAX = 0x80000000 + +} ctl_3d_tier_type_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Game tiers +typedef uint32_t ctl_3d_tier_profile_flags_t; +typedef enum _ctl_3d_tier_profile_flag_t +{ + CTL_3D_TIER_PROFILE_FLAG_TIER_1 = CTL_BIT(0), ///< Tier 1 Profile + CTL_3D_TIER_PROFILE_FLAG_TIER_2 = CTL_BIT(1), ///< Tier 2 Profile + CTL_3D_TIER_PROFILE_FLAG_TIER_RECOMMENDED = CTL_BIT(30),///< Recommended Tier Profile. If set other tier values shouldn't be set + CTL_3D_TIER_PROFILE_FLAG_MAX = 0x80000000 + +} ctl_3d_tier_profile_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Game Profile Capabilities. Typically these remain the same across +/// games. +typedef struct _ctl_3d_app_profiles_caps_t +{ + ctl_3d_tier_type_flags_t SupportedTierTypes; ///< [out] Tier of interest for capability check + uint64_t Reserved; ///< [in,out] Reserved for future + +} ctl_3d_app_profiles_caps_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Game Profile tiers +typedef struct _ctl_3d_app_profiles_t +{ + ctl_3d_tier_type_flag_t TierType; ///< [in] Tier type + ctl_3d_tier_profile_flags_t SupportedTierProfiles; ///< [out] Supported tier profiles bitmask + ctl_3d_tier_profile_flags_t DefaultEnabledTierProfiles; ///< [out] Default tiers which driver will enable if there is no user + ///< specific setting for global or per application + ctl_3d_tier_profile_flags_t CustomizationSupportedTierProfiles; ///< [out] Tiers supporting customization - reserved for future + ctl_3d_tier_profile_flags_t EnabledTierProfiles;///< [in,out] Tier profile(s) to be enabled/disabled in the case of a set + ///< call. For a get call this will return the currently enabled tiers + ctl_3d_tier_profile_flags_t CustomizationEnabledTierProfiles; ///< [in,out] Tier profile(s) which are customized. Caller shall call + ///< ::ctl_3d_tier_details_t to get specifics if any. + uint64_t Reserved; ///< [in,out] Reserved for future + +} ctl_3d_app_profiles_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Game Profile tiers details +typedef struct _ctl_3d_tier_details_t +{ + ctl_3d_tier_type_flag_t TierType; ///< [in] Tier type + ctl_3d_tier_profile_flag_t TierProfile; ///< [in] Tier profile(s) for get/set details + uint64_t Reserved[4]; ///< [in,out] Reserved for future + +} ctl_3d_tier_details_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Emulated Typed 64bit Atomics +typedef enum _ctl_emulated_typed_64bit_atomics_types_t +{ + CTL_EMULATED_TYPED_64BIT_ATOMICS_TYPES_DEFAULT = 0, ///< Default settings is based on workload/driver decision. + CTL_EMULATED_TYPED_64BIT_ATOMICS_TYPES_TURN_ON = 1, ///< Force Turn on + CTL_EMULATED_TYPED_64BIT_ATOMICS_TYPES_TURN_OFF = 2,///< Force Turn off + CTL_EMULATED_TYPED_64BIT_ATOMICS_TYPES_MAX + +} ctl_emulated_typed_64bit_atomics_types_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief VRR windowed BLT control possible. Reserved functionality +typedef enum _ctl_3d_vrr_windowed_blt_reserved_t +{ + CTL_3D_VRR_WINDOWED_BLT_RESERVED_AUTO = 0, ///< VRR windowed BLT auto + CTL_3D_VRR_WINDOWED_BLT_RESERVED_TURN_ON = 1, ///< VRR windowed BLT enable + CTL_3D_VRR_WINDOWED_BLT_RESERVED_TURN_OFF = 2, ///< VRR windowed BLT disable + CTL_3D_VRR_WINDOWED_BLT_RESERVED_MAX + +} ctl_3d_vrr_windowed_blt_reserved_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Global or per app values possible +typedef enum _ctl_3d_global_or_per_app_types_t +{ + CTL_3D_GLOBAL_OR_PER_APP_TYPES_NONE = 0, ///< none + CTL_3D_GLOBAL_OR_PER_APP_TYPES_PER_APP = 1, ///< Opt for per app settings + CTL_3D_GLOBAL_OR_PER_APP_TYPES_GLOBAL = 2, ///< Opt for global settings + CTL_3D_GLOBAL_OR_PER_APP_TYPES_MAX + +} ctl_3d_global_or_per_app_types_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief 3D feature capability details which will have range/supported and +/// default values +typedef struct _ctl_3d_feature_details_t +{ + ctl_3d_feature_t FeatureType; ///< [out] 3D feature type + ctl_property_value_type_t ValueType; ///< [out] Type of value + ctl_property_info_t Value; ///< [out] Union of various type of values for 3D features. For enum types + ///< this can be anisotropic/frame pacing etc. This member is valid iff + ///< ValueType is not CTL_PROPERTY_VALUE_TYPE_CUSTOM + int32_t CustomValueSize; ///< [in] CustomValue buffer size. Typically for a feature requiring custom + ///< struct, caller will know of it upfront and can provide the right size + ///< info here + void* pCustomValue; ///< [in,out] Pointer to a custom structure. Caller should allocate this + ///< buffer with known custom feature structure size. This member is valid + ///< iff ValueType is CTL_PROPERTY_VALUE_TYPE_CUSTOM + bool PerAppSupport; ///< [out] Flag indicating whether the feature is supported per application + ///< or not + int64_t ConflictingFeatures; ///< [out] Mask of ::ctl_3d_feature_t values which can't be enabled along + ///< with the mentioned FeatureType. If this is 0, it meant the feature + ///< doesn't have any conflicts with other features + int16_t FeatureMiscSupport; ///< [out] 3D Feature Miscellaneous support flags. This will be based on + ///< ::ctl_3d_feature_misc_flags_t + int16_t Reserved; ///< [out] Reserved + int16_t Reserved1; ///< [out] Reserved + int16_t Reserved2; ///< [out] Reserved + +} ctl_3d_feature_details_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief 3D feature which are controllable +typedef struct _ctl_3d_feature_caps_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint32_t NumSupportedFeatures; ///< [in,out] Number of elements in supported features array + ctl_3d_feature_details_t* pFeatureDetails; ///< [in,out] Array of feature details + +} ctl_3d_feature_caps_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief 3D feature for get/set +typedef struct _ctl_3d_feature_getset_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_3d_feature_t FeatureType; ///< [in] Features interested in + char* ApplicationName; ///< [in] Application name for which the property type is applicable. If + ///< this is an empty string then this will get/set global settings for the + ///< given adapter. Note that this should contain only the name of the + ///< application and not the system specific path + int8_t ApplicationNameLength; ///< [in] Length of ApplicationName string + bool bSet; ///< [in] Set this if it's a set call + ctl_property_value_type_t ValueType; ///< [in] Type of value. Caller has to ensure it provides the right value + ///< type which decides how one read the union structure below + ctl_property_t Value; ///< [in,out] Union of various type of values for 3D features. For enum + ///< types this can be anisotropic/frame pacing etc. This member is valid + ///< iff ValueType is not CTL_PROPERTY_VALUE_TYPE_CUSTOM + int32_t CustomValueSize; ///< [in] CustomValue buffer size. Typically for a feature requiring custom + ///< struct, caller will know of it upfront and cn provide the right size + ///< info here + void* pCustomValue; ///< [in,out] Pointer to a custom structure. Caller should allocate this + ///< buffer with known custom feature structure size. This member is valid + ///< iff ValueType is CTL_PROPERTY_VALUE_TYPE_CUSTOM + +} ctl_3d_feature_getset_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Load KMD gaming features. Restricted function +typedef struct _ctl_kmd_load_features_t +{ + ctl_application_id_t ReservedFuncID; ///< [in] Unique ID for reserved/special function + bool bLoad; ///< [in] If set, will load known KMD features. If not set will reset known + ///< KMD features to default + int64_t SubsetFeatureMask; ///< [in,out] Mask indicating the subset of KMD features within + ///< ::ctl_3d_feature_t values. Default of 0 indicate all KMD features + char* ApplicationName; ///< [in] Application name for which the KMD properties are loaded for. If + ///< this is an empty string then this will load global settings for the + ///< given adapter. Note that this should contain only the name of the + ///< application and not the system specific path + int8_t ApplicationNameLength; ///< [in] Length of ApplicationName string + int8_t CallerComponent; ///< [in] Caller component + int64_t Reserved[4]; ///< [in] Reserved field + +} ctl_kmd_load_features_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get 3D capabilities +/// +/// @details +/// - The application gets 3D 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_APIEXPORT ctl_result_t CTL_APICALL +ctlGetSupported3DCapabilities( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + ctl_3d_feature_caps_t* pFeatureCaps ///< [in,out][release] 3D properties + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get/Set 3D feature +/// +/// @details +/// - 3D 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_APIEXPORT ctl_result_t CTL_APICALL +ctlGetSet3DFeature( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + ctl_3d_feature_getset_t* pFeature ///< [in][release] 3D feature get/set parameter + ); + + +#if !defined(__GNUC__) +#pragma endregion // _3D +#endif +// Intel 'ctlApi' for Device Adapter +#if !defined(__GNUC__) +#pragma region display +#endif +/////////////////////////////////////////////////////////////////////////////// +/// @brief Handle of a display output instance +typedef struct _ctl_display_output_handle_t *ctl_display_output_handle_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Handle of a i2c pin-pair instance +typedef struct _ctl_i2c_pin_pair_handle_t *ctl_i2c_pin_pair_handle_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Check Driver version +/// +/// @details +/// - The application checks driver version +/// +/// @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_APIEXPORT ctl_result_t CTL_APICALL +ctlCheckDriverVersion( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter + ctl_version_info_t version_info ///< [in][release] Driver version info + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Enumerate devices +/// +/// @details +/// - The application enumerates all device adapters 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` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlEnumerateDevices( + 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 device instances. If count + ///< is zero, then the api will update the value with the total + ///< number of drivers available. If count is non-zero, then the api will + ///< only retrieve the number of drivers. + ///< If count is larger than the number of drivers available, then the api + ///< will update the value with the correct number of drivers available. + ctl_device_adapter_handle_t* phDevices ///< [in,out][optional][release][range(0, *pCount)] array of driver + ///< instance handles + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Enumerate display outputs +/// +/// @details +/// - Enumerates display output capabilities +/// +/// @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_APIEXPORT ctl_result_t CTL_APICALL +ctlEnumerateDisplayOutputs( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter + uint32_t* pCount, ///< [in,out][release] pointer to the number of display output instances. + ///< 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 drivers available, then the api + ///< will update the value with the correct number of drivers available. + ctl_display_output_handle_t* phDisplayOutputs ///< [in,out][optional][release][range(0, *pCount)] array of display output + ///< instance handles + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Enumerate I2C Pin Pairs +/// +/// @details +/// - Returns available list of I2C Pin-Pairs on a requested adapter +/// +/// @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_POINTER - "The incoming pointer pCount is null" +/// - ::CTL_RESULT_ERROR_INVALID_SIZE - "The supplied Count is not equal to actual number of i2c pin-pair instances" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlEnumerateI2CPinPairs( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to device adapter + uint32_t* pCount, ///< [in,out][release] pointer to the number of i2c pin-pair instances. If + ///< count is zero, then the api will update the value with the total + ///< number of i2c pin-pair instances available. If count is non-zero and + ///< matches the avaialble number of pin-pairs, then the api will only + ///< return the avaialble number of i2c pin-pair instances in phI2cPinPairs. + ctl_i2c_pin_pair_handle_t* phI2cPinPairs ///< [out][optional][release][range(0, *pCount)] array of i2c pin pair + ///< instance handles. Need to be allocated by Caller when supplying the + ///< *pCount > 0. + ///< If Count is not equal to actual number of i2c pin-pair instances, it + ///< will return CTL_RESULT_ERROR_INVALID_SIZE. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief OS specific Display identifiers +typedef union _ctl_os_display_encoder_identifier_t +{ + uint32_t WindowsDisplayEncoderID; ///< [out] Windows OS Display encoder ID + ctl_generic_void_datatype_t DisplayEncoderID; ///< [out] Display encoder ID for non-windows OS + +} ctl_os_display_encoder_identifier_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Various display types +typedef enum _ctl_display_output_types_t +{ + CTL_DISPLAY_OUTPUT_TYPES_INVALID = 0, ///< Invalid + CTL_DISPLAY_OUTPUT_TYPES_DISPLAYPORT = 1, ///< DisplayPort + CTL_DISPLAY_OUTPUT_TYPES_HDMI = 2, ///< HDMI + CTL_DISPLAY_OUTPUT_TYPES_DVI = 3, ///< DVI + CTL_DISPLAY_OUTPUT_TYPES_MIPI = 4, ///< MIPI + CTL_DISPLAY_OUTPUT_TYPES_CRT = 5, ///< CRT + CTL_DISPLAY_OUTPUT_TYPES_MAX + +} ctl_display_output_types_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Supported output bits per color (bpc) bitmasks +typedef uint32_t ctl_output_bpc_flags_t; +typedef enum _ctl_output_bpc_flag_t +{ + CTL_OUTPUT_BPC_FLAG_6BPC = CTL_BIT(0), ///< [out] Is 6bpc supported + CTL_OUTPUT_BPC_FLAG_8BPC = CTL_BIT(1), ///< [out] Is 8bpc supported + CTL_OUTPUT_BPC_FLAG_10BPC = CTL_BIT(2), ///< [out] Is 10bpc supported + CTL_OUTPUT_BPC_FLAG_12BPC = CTL_BIT(3), ///< [out] Is 12bpc supported + CTL_OUTPUT_BPC_FLAG_MAX = 0x80000000 + +} ctl_output_bpc_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Display output features. This will indicate only the high level +/// capabilities +typedef uint32_t ctl_std_display_feature_flags_t; +typedef enum _ctl_std_display_feature_flag_t +{ + CTL_STD_DISPLAY_FEATURE_FLAG_HDCP = CTL_BIT(0), ///< [out] Is HDCP supported + CTL_STD_DISPLAY_FEATURE_FLAG_HD_AUDIO = CTL_BIT(1), ///< [out] Is HD Audio supported + CTL_STD_DISPLAY_FEATURE_FLAG_PSR = CTL_BIT(2), ///< [out] Is VESA PSR supported + CTL_STD_DISPLAY_FEATURE_FLAG_ADAPTIVESYNC_VRR = CTL_BIT(3), ///< [out] Is VESA Adaptive Sync or HDMI VRR supported + 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; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Advanced Graphics Features provided by Intel Graphics Adapter. This +/// will indicate only the high level capabilities +typedef uint32_t ctl_intel_display_feature_flags_t; +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; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Attached Display Mux Type +typedef enum _ctl_attached_display_mux_type_t +{ + CTL_ATTACHED_DISPLAY_MUX_TYPE_NATIVE = 0, ///< [out] Native DP / HDMI + CTL_ATTACHED_DISPLAY_MUX_TYPE_THUNDERBOLT = 1, ///< [out] Thunderbolt + CTL_ATTACHED_DISPLAY_MUX_TYPE_TYPE_C = 2, ///< [out] USB Type C + CTL_ATTACHED_DISPLAY_MUX_TYPE_USB4 = 3, ///< [out] USB4 + CTL_ATTACHED_DISPLAY_MUX_TYPE_MAX + +} ctl_attached_display_mux_type_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Signal Standard +typedef enum _ctl_signal_standard_type_t +{ + CTL_SIGNAL_STANDARD_TYPE_UNKNOWN = 0, ///< [out] Unknown Signal Standard + CTL_SIGNAL_STANDARD_TYPE_CUSTOM = 1, ///< [out] Custom added timing + CTL_SIGNAL_STANDARD_TYPE_DMT = 2, ///< [out] DMT timing + CTL_SIGNAL_STANDARD_TYPE_GTF = 3, ///< [out] GTF Timing + CTL_SIGNAL_STANDARD_TYPE_CVT = 4, ///< [out] CVT Timing + CTL_SIGNAL_STANDARD_TYPE_CTA = 5, ///< [out] CTA Timing + CTL_SIGNAL_STANDARD_TYPE_MAX + +} ctl_signal_standard_type_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Protocol Converter Location +typedef uint32_t ctl_protocol_converter_location_flags_t; +typedef enum _ctl_protocol_converter_location_flag_t +{ + CTL_PROTOCOL_CONVERTER_LOCATION_FLAG_ONBOARD = CTL_BIT(0), ///< [out] OnBoard Protocol Converter + CTL_PROTOCOL_CONVERTER_LOCATION_FLAG_EXTERNAL = CTL_BIT(1), ///< [out] External Dongle + CTL_PROTOCOL_CONVERTER_LOCATION_FLAG_MAX = 0x80000000 + +} ctl_protocol_converter_location_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief [out] Display Output configuration related flags which indicate how +/// the output pixel stream drive the panel +typedef uint32_t ctl_display_config_flags_t; +typedef enum _ctl_display_config_flag_t +{ + CTL_DISPLAY_CONFIG_FLAG_DISPLAY_ACTIVE = CTL_BIT(0),///< [out] DisplayActive 0: InActive 1: Active + CTL_DISPLAY_CONFIG_FLAG_DISPLAY_ATTACHED = CTL_BIT(1), ///< [out] DisplayAttached.This Bit indicates if any dongle/display/hub is + ///< attached to the encoder. 0: Not Attached 1: Attached + CTL_DISPLAY_CONFIG_FLAG_IS_DONGLE_CONNECTED_TO_ENCODER = CTL_BIT(2),///< [out] This BIT will be set if a dongle/hub/onboard protocol converter + ///< , is attached to the encoder + CTL_DISPLAY_CONFIG_FLAG_DITHERING_ENABLED = CTL_BIT(3), ///< [out] This BIT will be set if dithering is enabled on the encoder + CTL_DISPLAY_CONFIG_FLAG_MAX = 0x80000000 + +} ctl_display_config_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief [out] Encoder configuration related flags which indicate how the +/// output pixel stream drive the panel +typedef uint32_t ctl_encoder_config_flags_t; +typedef enum _ctl_encoder_config_flag_t +{ + CTL_ENCODER_CONFIG_FLAG_INTERNAL_DISPLAY = CTL_BIT(0), ///< [out] Internal connection or not + CTL_ENCODER_CONFIG_FLAG_VESA_TILED_DISPLAY = CTL_BIT(1),///< [out] VESA DisplayID based tiled display which is driven by either + ///< multiple physical connections (DisplayPort SST) or virtual streams + ///< (DisplayPort MST) + CTL_ENCODER_CONFIG_FLAG_TYPEC_CAPABLE = CTL_BIT(2), ///< [out] This is set if encoder supports type c display + CTL_ENCODER_CONFIG_FLAG_TBT_CAPABLE = CTL_BIT(3), ///< [out] This is set if encoder supports Thunderbolt display + CTL_ENCODER_CONFIG_FLAG_DITHERING_SUPPORTED = CTL_BIT(4), ///< [out] This BIT will be set if encoder supports dithering + CTL_ENCODER_CONFIG_FLAG_VIRTUAL_DISPLAY = CTL_BIT(5), ///< [out] This BIT will be set if this is a virtual display.Hardware based + ///< features will not be applicable to this display.For collage display + ///< this will be set for the virtual output created by driver. For split + ///< display this will be set for the virtual split displays created out of + ///< one single physical display + CTL_ENCODER_CONFIG_FLAG_HIDDEN_DISPLAY = CTL_BIT(6),///< [out] This BIT will be set if display is hidden from OS + CTL_ENCODER_CONFIG_FLAG_COLLAGE_DISPLAY = CTL_BIT(7), ///< [out] This BIT will be set if this is a collage display + CTL_ENCODER_CONFIG_FLAG_SPLIT_DISPLAY = CTL_BIT(8), ///< [out] This BIT will be set if this is a split display + CTL_ENCODER_CONFIG_FLAG_COMPANION_DISPLAY = CTL_BIT(9), ///< [out] This BIT will be set if this is a companion display + CTL_ENCODER_CONFIG_FLAG_MGPU_COLLAGE_DISPLAY = CTL_BIT(10), ///< [out] This BIT will be set if this is a Multi GPU collage display + CTL_ENCODER_CONFIG_FLAG_MAX = 0x80000000 + +} ctl_encoder_config_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Display Timing +typedef struct _ctl_display_timing_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint64_t PixelClock; ///< [out] Pixel Clock in Hz + uint32_t HActive; ///< [out] Horizontal Active + uint32_t VActive; ///< [out] Vertical Active + uint32_t HTotal; ///< [out] Horizontal Total + uint32_t VTotal; ///< [out] Vertical Total + uint32_t HBlank; ///< [out] Horizontal Blank + uint32_t VBlank; ///< [out] Vertical Blank + uint32_t HSync; ///< [out] Horizontal Blank + uint32_t VSync; ///< [out] Vertical Blank + float RefreshRate; ///< [out] Refresh Rate + ctl_signal_standard_type_t SignalStandard; ///< [out] Signal Standard + uint8_t VicId; ///< [out] VIC ID for CTA timings + +} ctl_display_timing_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief This structure will contain the properties of the display currently +/// attached to the encoder. +typedef struct _ctl_display_properties_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_os_display_encoder_identifier_t Os_display_encoder_handle; ///< [out] OS specific Display ID + ctl_display_output_types_t Type; ///< [out] Device Type from display HW stand point. If a DisplayPort + ///< protocol converter is involved, this will indicate it's DisplayPort. + ///< The protocol converter's output will be available from + ///< ProtocolConverterOutput field + ctl_attached_display_mux_type_t AttachedDisplayMuxType; ///< [out] Attached Display Mux Type + ctl_display_output_types_t ProtocolConverterOutput; ///< [out] Protocol output type which can be used if config flags indicate + ///< it's a protocol converter. If it's not a protocol converter this will + ///< be set to CTL_DISPLAY_OUTPUT_TYPES_INVALID + ctl_revision_datatype_t SupportedSpec; ///< [out] Supported industry spec version. + ctl_output_bpc_flags_t SupportedOutputBPCFlags; ///< [out] Supported output bits per color. Refer ::ctl_output_bpc_flag_t. + ///< This is independent of RGB or YCbCr output.This is the max BPC + ///< supported.BPC will vary per mode based on restrictions like bandwidth + ///< and monitor support + ctl_protocol_converter_location_flags_t ProtocolConverterType; ///< [out] Currently Active Protocol Converter. Refer + ///< ::ctl_protocol_converter_location_flag_t + ctl_display_config_flags_t DisplayConfigFlags; ///< [out] Output configuration related flags which indicate how the output + ///< pixel stream drive the panel. Refer ::ctl_display_config_flag_t + ctl_std_display_feature_flags_t FeatureEnabledFlags;///< [out] Enabled Display features.Refer ::ctl_std_display_feature_flag_t. + ctl_std_display_feature_flags_t FeatureSupportedFlags; ///< [out] Display Supported feature.Refer ::ctl_std_display_feature_flag_t + ctl_intel_display_feature_flags_t AdvancedFeatureEnabledFlags; ///< [out] Enabled advanced feature.Refer + ///< ::ctl_intel_display_feature_flag_t. + ctl_intel_display_feature_flags_t AdvancedFeatureSupportedFlags;///< [out] Supported advanced feature.Refer + ///< ::ctl_intel_display_feature_flag_t. + ctl_display_timing_t Display_Timing_Info; ///< [out] Applied Timing on the Display + uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes + +} ctl_display_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Adapter's display encoder properties +typedef struct _ctl_adapter_display_encoder_properties_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_os_display_encoder_identifier_t Os_display_encoder_handle; ///< [out] OS specific Display ID + ctl_display_output_types_t Type; ///< [out] Device Type from display HW stand point. If a DisplayPort + ///< protocol converter is involved, this will indicate it's DisplayPort. + ///< The protocol converter's output will be available from + ///< ProtocolConverterOutput field + bool IsOnBoardProtocolConverterOutputPresent; ///< [out] Protocol output type which can be used if it's a protocol + ///< converter. If it's not a protocol converter this will be set to + ///< CTL_DISPLAY_OUTPUT_TYPES_INVALID + ctl_revision_datatype_t SupportedSpec; ///< [out] Supported industry spec version + ctl_output_bpc_flags_t SupportedOutputBPCFlags; ///< [out] Supported output bits per color. Refer ::ctl_output_bpc_flag_t. + ///< This is independent of RGB or YCbCr output.This is the max BPC + ///< supported.BPC will vary per mode based on restrictions like bandwidth + ///< and monitor support + ctl_encoder_config_flags_t EncoderConfigFlags; ///< [out] Output configuration related flags which indicate how the output + ///< pixel stream drive the panel. Refer ::ctl_encoder_config_flag_t + ///< Note: + ///< Virtual = 1: This indicates that its a software display. Hardware + ///< based features will not be applicable to this display. + ///< Collage=1,Virtual=1: Indicates the fake display output created by + ///< driver which has the combined resolution of multiple physical displays + ///< involved in collage configuration + ///< Collage=1,Virtual=0: Indicates the child physical displays involved + ///< in a collage configuration. These are real physical outputs + ///< Split=1,Virtual=1 : Indicates the fake display output created by + ///< driver which occupies a portion of a real physical display + ///< Split=1,Virtual=0 : Indicates the physical display which got split + ///< to form multiple split displays + ///< Split=1,Collage=1 : Invalid combination + ///< MgpuCollage=1,Collage=1,Virtual=1: Indicates the fake display + ///< output created by driver which has the combined resolution of multiple + ///< physical displays spread across multiple GPUs involved in Multi-GPU + ///< collage configuration + ///< MgpuCollage=1,Collage=1,Virtual=0: Indicates the child physical + ///< displays involved in a Multi-GPU collage configuration. These are real + ///< physical outputs + ctl_std_display_feature_flags_t FeatureSupportedFlags; ///< [out] Adapter Supported feature flags. Refer + ///< ::ctl_std_display_feature_flag_t + ctl_intel_display_feature_flags_t AdvancedFeatureSupportedFlags;///< [out] Advanced Features Supported by the Adapter. Refer + ///< ::ctl_intel_display_feature_flag_t + uint32_t ReservedFields[16]; ///< [out] Reserved field of 60 bytes + +} ctl_adapter_display_encoder_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Device Properties +/// +/// @details +/// - The application gets device 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 == pProperties` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetDeviceProperties( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to control device adapter + ctl_device_adapter_properties_t* pProperties ///< [in,out][release] Query result for device properties + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Display Properties +/// +/// @details +/// - The application gets display properties +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pProperties` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetDisplayProperties( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_display_properties_t* pProperties ///< [in,out][release] Query result for display properties + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Adapter Display encoder Properties +/// +/// @details +/// - The application gets the graphic adapters display encoder properties +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pProperties` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetAdaperDisplayEncoderProperties( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_adapter_display_encoder_properties_t* pProperties ///< [in,out][release] Query result for adapter display encoder properties + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Level0 Device handle +/// +/// @details +/// - The application gets OneAPI Level0 Device handles +/// +/// @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 == pZeDevice` +/// + `nullptr == hInstance` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetZeDevice( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + void* pZeDevice, ///< [out][release] ze_device handle + void** hInstance ///< [out][release] Module instance which caller can use to get export + ///< functions directly + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Various sharpness filter types +typedef uint32_t ctl_sharpness_filter_type_flags_t; +typedef enum _ctl_sharpness_filter_type_flag_t +{ + CTL_SHARPNESS_FILTER_TYPE_FLAG_NON_ADAPTIVE = CTL_BIT(0), ///< Non-adaptive sharpness + CTL_SHARPNESS_FILTER_TYPE_FLAG_ADAPTIVE = CTL_BIT(1), ///< Adaptive sharpness + CTL_SHARPNESS_FILTER_TYPE_FLAG_MAX = 0x80000000 + +} ctl_sharpness_filter_type_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Sharpness filter properties +typedef struct _ctl_sharpness_filter_properties_t +{ + ctl_sharpness_filter_type_flags_t FilterType; ///< [out] Filter type. Refer ::ctl_sharpness_filter_type_flag_t + ctl_property_range_info_t FilterDetails; ///< [out] Min, max & step size information + +} ctl_sharpness_filter_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Various sharpness filter types +typedef struct _ctl_sharpness_caps_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_sharpness_filter_type_flags_t SupportedFilterFlags; ///< [out] Supported sharpness filters for a given display output. Refer + ///< ::ctl_sharpness_filter_type_flag_t + uint8_t NumFilterTypes; ///< [out] Number of elements in filter properties array + ctl_sharpness_filter_properties_t* pFilterProperty; ///< [in,out] Array of filter properties structure describing supported + ///< filter capabilities. Caller should provide a pre-allocated memory for + ///< this. + +} ctl_sharpness_caps_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Current sharpness setting +typedef struct _ctl_sharpness_settings_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + bool Enable; ///< [in,out] Current or new state of sharpness setting + ctl_sharpness_filter_type_flags_t FilterType; ///< [in,out] Current or new filter to be set. Refer + ///< ::ctl_sharpness_filter_type_flag_t + float Intensity; ///< [in,out] Setting intensity to be applied + +} ctl_sharpness_settings_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Sharpness capability +/// +/// @details +/// - Returns sharpness capability +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pSharpnessCaps` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetSharpnessCaps( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_sharpness_caps_t* pSharpnessCaps ///< [in,out][release] Query result for sharpness capability + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Sharpness setting +/// +/// @details +/// - Returns current sharpness settings +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pSharpnessSettings` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetCurrentSharpness( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_sharpness_settings_t* pSharpnessSettings ///< [in,out][release] Query result for sharpness current settings + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set Sharpness setting +/// +/// @details +/// - Set current sharpness settings +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pSharpnessSettings` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlSetCurrentSharpness( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_sharpness_settings_t* pSharpnessSettings ///< [in][release] Set sharpness current settings + ); + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_I2C_MAX_DATA_SIZE +/// @brief I2C Maximum data size +#define CTL_I2C_MAX_DATA_SIZE 0x0080 +#endif // CTL_I2C_MAX_DATA_SIZE + +/////////////////////////////////////////////////////////////////////////////// +/// @brief I2C Access Args input Flags bitmasks +typedef uint32_t ctl_i2c_flags_t; +typedef enum _ctl_i2c_flag_t +{ + CTL_I2C_FLAG_ATOMICI2C = CTL_BIT(0), ///< Force Atomic I2C. + CTL_I2C_FLAG_1BYTE_INDEX = CTL_BIT(1), ///< 1-byte Indexed operation. If no Index Size flag set, decided based on + ///< Offset Value. + CTL_I2C_FLAG_2BYTE_INDEX = CTL_BIT(2), ///< 2-byte Indexed operation. If no Index Size flag set, decided based on + ///< Offset Value. + CTL_I2C_FLAG_4BYTE_INDEX = CTL_BIT(3), ///< 4-byte Indexed operation. If no Index Size flag set, decided based on + ///< Offset Value. + CTL_I2C_FLAG_SPEED_SLOW = CTL_BIT(4), ///< If no Speed Flag is set, defaults to Best Option possible. + 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; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief I2C access arguments +typedef struct _ctl_i2c_access_args_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint32_t DataSize; ///< [in,out] Valid data size + uint32_t Address; ///< [in] Address to read or write + ctl_operation_type_t OpType; ///< [in] Operation type, 1 for Read, 2 for Write, for Write operation, App + ///< needs to run with admin privileges + uint32_t Offset; ///< [in] Offset + ctl_i2c_flags_t Flags; ///< [in] I2C Flags. Refer ::ctl_i2c_flag_t + uint64_t RAD; ///< [in] RAD, For Future use, to be used for branch devices, Interface + ///< will be provided to get RAD + uint8_t Data[CTL_I2C_MAX_DATA_SIZE]; ///< [in,out] Data array + +} ctl_i2c_access_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief I2C Access +/// +/// @details +/// - Interface to access I2C using display handle as identifier. I2C +/// driver override flags are supported only for HDMI displays. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pI2cAccessArgs` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" +/// - ::CTL_RESULT_ERROR_INVALID_SIZE - "Invalid I2C data size" +/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" +/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +/// - ::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 - "Kernal mode driver call failure" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlI2CAccess( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_i2c_access_args_t* pI2cAccessArgs ///< [in,out] I2c access arguments + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief I2C Access on PinPair Args input Flags bitmasks +typedef uint32_t ctl_i2c_pinpair_flags_t; +typedef enum _ctl_i2c_pinpair_flag_t +{ + CTL_I2C_PINPAIR_FLAG_ATOMICI2C = CTL_BIT(0), ///< Force Atomic I2C. + CTL_I2C_PINPAIR_FLAG_1BYTE_INDEX = CTL_BIT(1), ///< 1-byte Indexed operation. If no Index Size flag set, decided based on + ///< Offset Value. + CTL_I2C_PINPAIR_FLAG_2BYTE_INDEX = CTL_BIT(2), ///< 2-byte Indexed operation. If no Index Size flag set, decided based on + ///< Offset Value. + CTL_I2C_PINPAIR_FLAG_4BYTE_INDEX = CTL_BIT(3), ///< 4-byte Indexed operation. If no Index Size flag set, decided based on + ///< Offset Value. + CTL_I2C_PINPAIR_FLAG_SPEED_SLOW = CTL_BIT(4), ///< If no Speed Flag is set, defaults to Best Option possible. + CTL_I2C_PINPAIR_FLAG_SPEED_FAST = CTL_BIT(5), ///< If no Speed Flag is set, defaults to Best Option possible. + CTL_I2C_PINPAIR_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_PINPAIR_FLAG_MAX = 0x80000000 + +} ctl_i2c_pinpair_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief I2C access on Pin Pair arguments +typedef struct _ctl_i2c_access_pinpair_args_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint32_t DataSize; ///< [in,out] Valid data size + uint32_t Address; ///< [in] Address to read or write + ctl_operation_type_t OpType; ///< [in] Operation type, 1 for Read, 2 for Write, for Write operation, App + ///< needs to run with admin privileges + uint32_t Offset; ///< [in] Offset + ctl_i2c_pinpair_flags_t Flags; ///< [in] I2C Flags. Refer ::ctl_i2c_pinpair_flag_t + uint8_t Data[CTL_I2C_MAX_DATA_SIZE]; ///< [in,out] Data array + uint32_t ReservedFields[4]; ///< [in] Reserved for future use, must be set to Zero. + +} ctl_i2c_access_pinpair_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief I2C Access On Pin Pair +/// +/// @details +/// - Interface to access I2C using pin-pair handle as identifier. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hI2cPinPair` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pI2cAccessArgs` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" +/// - ::CTL_RESULT_ERROR_INVALID_SIZE - "Invalid I2C data size" +/// - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid Args passed" +/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" +/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +/// - ::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 - "Kernal mode driver call failure" +/// - ::CTL_RESULT_ERROR_INVALID_NULL_HANDLE - "Invalid or Null handle passed" +/// - ::CTL_RESULT_ERROR_EXTERNAL_DISPLAY_ATTACHED - "Write to Address not allowed when Display is connected" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlI2CAccessOnPinPair( + ctl_i2c_pin_pair_handle_t hI2cPinPair, ///< [in] Handle to I2C pin pair. + ctl_i2c_access_pinpair_args_t* pI2cAccessArgs ///< [in,out] I2c access arguments. + ); + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_AUX_MAX_DATA_SIZE +/// @brief Aux Maximum data size +#define CTL_AUX_MAX_DATA_SIZE 132 +#endif // CTL_AUX_MAX_DATA_SIZE + +/////////////////////////////////////////////////////////////////////////////// +/// @brief AUX Flags bitmasks +typedef uint32_t ctl_aux_flags_t; +typedef enum _ctl_aux_flag_t +{ + CTL_AUX_FLAG_NATIVE_AUX = CTL_BIT(0), ///< For Native AUX operation + CTL_AUX_FLAG_I2C_AUX = CTL_BIT(1), ///< For I2C AUX operation + CTL_AUX_FLAG_I2C_AUX_MOT = CTL_BIT(2), ///< For I2C AUX MOT operation + CTL_AUX_FLAG_MAX = 0x80000000 + +} ctl_aux_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief AUX access arguments +typedef struct _ctl_aux_access_args_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_operation_type_t OpType; ///< [in] Operation type, 1 for Read, 2 for Write, for Write operation, App + ///< needs to run with admin privileges + ctl_aux_flags_t Flags; ///< [in] Aux Flags. Refer ::ctl_aux_flag_t + uint32_t Address; ///< [in] Address to read or write + uint64_t RAD; ///< [in] RAD, For Future use, to be used for branch devices, Interface + ///< will be provided to get RAD + uint32_t PortID; ///< [in] Port ID, For Future use, to be used for SST tiled devices + uint32_t DataSize; ///< [in,out] Valid data size + uint8_t Data[CTL_AUX_MAX_DATA_SIZE]; ///< [in,out] Data array + +} ctl_aux_access_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Aux Access +/// +/// @details +/// - The application does Aux access, PSR needs to be disabled for AUX +/// call. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pAuxAccessArgs` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" +/// - ::CTL_RESULT_ERROR_INVALID_SIZE - "Invalid AUX data size" +/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" +/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +/// - ::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_INVALID_AUX_ACCESS_FLAG - "Invalid flag for AUX access" +/// - ::CTL_RESULT_ERROR_KMD_CALL - "Kernal mode driver call failure" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlAUXAccess( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_aux_access_args_t* pAuxAccessArgs ///< [in,out] Aux access arguments + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Power saving features (Each individual feature's set & get call can be +/// called only once at a time) +typedef uint32_t ctl_power_optimization_flags_t; +typedef enum _ctl_power_optimization_flag_t +{ + CTL_POWER_OPTIMIZATION_FLAG_FBC = CTL_BIT(0), ///< Frame buffer compression + CTL_POWER_OPTIMIZATION_FLAG_PSR = CTL_BIT(1), ///< Panel self refresh + CTL_POWER_OPTIMIZATION_FLAG_DPST = CTL_BIT(2), ///< Display power saving technology (Panel technology dependent) + CTL_POWER_OPTIMIZATION_FLAG_LRR = CTL_BIT(3), ///< Low refresh rate (LRR/ALRR/UBRR), UBRR is supported only for IGCC and + ///< NDA clients. UBZRR and UBLRR both can not be enabled at the same time, + ///< only one can be enabled at a given time + CTL_POWER_OPTIMIZATION_FLAG_LACE = CTL_BIT(4), ///< Lighting Aware Contrast Enhancement + CTL_POWER_OPTIMIZATION_FLAG_MAX = 0x80000000 + +} ctl_power_optimization_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief GPU/Panel/TCON dependent power optimization technology +typedef uint32_t ctl_power_optimization_dpst_flags_t; +typedef enum _ctl_power_optimization_dpst_flag_t +{ + CTL_POWER_OPTIMIZATION_DPST_FLAG_BKLT = CTL_BIT(0), ///< Intel DPST with Backlight control + CTL_POWER_OPTIMIZATION_DPST_FLAG_PANEL_CABC = CTL_BIT(1), ///< Panel TCON specific Content Adaptive Control mechanism + CTL_POWER_OPTIMIZATION_DPST_FLAG_OPST = CTL_BIT(2), ///< Intel OLED Power Saving Technology + CTL_POWER_OPTIMIZATION_DPST_FLAG_ELP = CTL_BIT(3), ///< TCON based Edge Luminance Profile + CTL_POWER_OPTIMIZATION_DPST_FLAG_EPSM = CTL_BIT(4), ///< Extra power saving mode + CTL_POWER_OPTIMIZATION_DPST_FLAG_APD = CTL_BIT(5), ///< Adaptive Pixel Dimming + CTL_POWER_OPTIMIZATION_DPST_FLAG_PIXOPTIX = CTL_BIT(6), ///< TCON+ based DPST like solution + CTL_POWER_OPTIMIZATION_DPST_FLAG_MAX = 0x80000000 + +} ctl_power_optimization_dpst_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Power Source +typedef enum _ctl_power_source_t +{ + CTL_POWER_SOURCE_AC = 0, ///< Power Source AC + CTL_POWER_SOURCE_DC = 1, ///< Power Source DC + CTL_POWER_SOURCE_MAX + +} ctl_power_source_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Power Optimization Plan +typedef enum _ctl_power_optimization_plan_t +{ + CTL_POWER_OPTIMIZATION_PLAN_BALANCED = 0, ///< Balanced mode + CTL_POWER_OPTIMIZATION_PLAN_HIGH_PERFORMANCE = 1, ///< High Performance Mode + CTL_POWER_OPTIMIZATION_PLAN_POWER_SAVER = 2, ///< Power Saver Mode + CTL_POWER_OPTIMIZATION_PLAN_MAX + +} ctl_power_optimization_plan_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Type of low refresh rate feature +typedef uint32_t ctl_power_optimization_lrr_flags_t; +typedef enum _ctl_power_optimization_lrr_flag_t +{ + CTL_POWER_OPTIMIZATION_LRR_FLAG_LRR10 = CTL_BIT(0), ///< LRR 1.0 + CTL_POWER_OPTIMIZATION_LRR_FLAG_LRR20 = CTL_BIT(1), ///< LRR 2.0 + CTL_POWER_OPTIMIZATION_LRR_FLAG_LRR25 = CTL_BIT(2), ///< LRR 2.5 + CTL_POWER_OPTIMIZATION_LRR_FLAG_ALRR = CTL_BIT(3), ///< Autonomous LRR + CTL_POWER_OPTIMIZATION_LRR_FLAG_UBLRR = CTL_BIT(4), ///< User based low refresh rate + CTL_POWER_OPTIMIZATION_LRR_FLAG_UBZRR = CTL_BIT(5), ///< User based zero refresh rate + CTL_POWER_OPTIMIZATION_LRR_FLAG_MAX = 0x80000000 + +} ctl_power_optimization_lrr_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Power optimization caps +typedef struct _ctl_power_optimization_caps_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_power_optimization_flags_t SupportedFeatures; ///< [out] Supported power optimization features. Refer + ///< ::ctl_power_optimization_flag_t + +} ctl_power_optimization_caps_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Power optimization features +/// +/// @details +/// - Returns power optimization capabilities +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pPowerOptimizationCaps` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetPowerOptimizationCaps( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_power_optimization_caps_t* pPowerOptimizationCaps ///< [in,out][release] Query result for power optimization features + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief LRR detailed settings +typedef struct _ctl_power_optimization_lrr_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_power_optimization_lrr_flags_t SupportedLRRTypes; ///< [out] LRR type(s). Refer ::ctl_power_optimization_lrr_flag_t + ctl_power_optimization_lrr_flags_t CurrentLRRTypes; ///< [in,out] Current enabled LRR type(s) or the LRR type(s) to set to. + ///< Refer ::ctl_power_optimization_lrr_flag_t + bool bRequirePSRDisable; ///< [out] Require PSR disable for any change in the selected LRR feature. + ///< Caller can re-enable PSR once the respective LRR feature is + ///< enable/disabled. E.g. for UBRR based on platform this flag may not be + ///< set in which case caller doesn't need to do an explicit PSR disable + uint16_t LowRR; ///< [out] Lowest RR used for LRR functionality if known to source + +} ctl_power_optimization_lrr_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief PSR detailed settings +typedef struct _ctl_power_optimization_psr_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint8_t PSRVersion; ///< [in,out] A value of 1 means PSR1, 2 means PSR2 + bool FullFetchUpdate; ///< [in,out] Full fetch and update + +} ctl_power_optimization_psr_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief DPST detailed settings +typedef struct _ctl_power_optimization_dpst_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint8_t MinLevel; ///< [out] Minimum supported aggressiveness level + uint8_t MaxLevel; ///< [out] Maximum supported aggressiveness level + uint8_t Level; ///< [in,out] Current aggressiveness level to be set + ctl_power_optimization_dpst_flags_t SupportedFeatures; ///< [out] Supported features + ctl_power_optimization_dpst_flags_t EnabledFeatures;///< [in,out] Features enabled or to be enabled. Fill only one feature for + ///< SET call + +} ctl_power_optimization_dpst_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Feature specific power optimization data +typedef union _ctl_power_optimization_feature_specific_info_t +{ + ctl_power_optimization_lrr_t LRRInfo; ///< [out] LRR info + ctl_power_optimization_psr_t PSRInfo; ///< [in,out] PSR info + ctl_power_optimization_dpst_t DPSTInfo; ///< [in,out] DPST info + +} ctl_power_optimization_feature_specific_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Power optimization settings +typedef struct _ctl_power_optimization_settings_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_power_optimization_plan_t PowerOptimizationPlan;///< [in] Power optimization power plan (max power/max perf/balanced) + ctl_power_optimization_flags_t PowerOptimizationFeature;///< [in] Power optimization feature interested in. Refer + ///< ::ctl_power_optimization_flag_t + bool Enable; ///< [in,out] Enable state + ctl_power_optimization_feature_specific_info_t FeatureSpecificData; ///< [in,out] Data specific to the feature caller is interested in + ctl_power_source_t PowerSource; ///< [in] AC/DC + +} ctl_power_optimization_settings_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Brightness settings for SET call +typedef struct _ctl_set_brightness_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint32_t TargetBrightness; ///< [in] The brightness level that the display need to transitioning to in + ///< milli-percentage. Range is 0-100000 (100%) + uint32_t SmoothTransitionTimeInMs; ///< [in] Transition Time for brightness to take effect in milli-seconds. + ///< If its 0 then it will be an immediate change. Maximum possible value + ///< is 1000ms. + uint32_t ReservedFields[4]; ///< [in] Reserved for future use + +} ctl_set_brightness_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Brightness settings for GET call +typedef struct _ctl_get_brightness_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint32_t TargetBrightness; ///< [out] The brightness level that the display is currently transitioning + ///< to in milli-percentage. If not in a transition, this should equal the + ///< current brightness. Range is 0-100000 (100%) + uint32_t CurrentBrightness; ///< [out] The current brightness level of the display in milli-percentage + uint32_t ReservedFields[4]; ///< [out] Reserved for future use + +} ctl_get_brightness_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Power optimization setting +/// +/// @details +/// - Returns power optimization setting for a specific feature +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pPowerOptimizationSettings` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INVALID_POWERFEATURE_OPTIMIZATION_FLAG - "Unsupported PowerOptimizationFeature" +/// - ::CTL_RESULT_ERROR_INVALID_POWERSOURCE_TYPE_FOR_DPST - "DPST is supported only in DC Mode" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetPowerOptimizationSetting( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_power_optimization_settings_t* pPowerOptimizationSettings ///< [in,out][release] Power optimization data to be fetched + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set Power optimization setting +/// +/// @details +/// - Set power optimization setting for a specific feature +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pPowerOptimizationSettings` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INVALID_POWERFEATURE_OPTIMIZATION_FLAG - "Unsupported PowerOptimizationFeature" +/// - ::CTL_RESULT_ERROR_INVALID_POWERSOURCE_TYPE_FOR_DPST - "DPST is supported only in DC Mode" +/// - ::CTL_RESULT_ERROR_SET_FBC_FEATURE_NOT_SUPPORTED - "Set FBC Feature not supported" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlSetPowerOptimizationSetting( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_power_optimization_settings_t* pPowerOptimizationSettings ///< [in][release] Power optimization data to be applied + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set Brightness on companion display +/// +/// @details +/// - Set Brightness for a target display. Currently support is only for +/// companion display. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pSetBrightnessSetting` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid Brightness data passed as argument" +/// - ::CTL_RESULT_ERROR_DISPLAY_NOT_ACTIVE - "Display not active" +/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Currently Brightness API is supported only on companion display" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlSetBrightnessSetting( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_set_brightness_t* pSetBrightnessSetting ///< [in][release] Brightness settings to be applied + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Brightness setting +/// +/// @details +/// - Get Brightness for a target display. Currently support is only for +/// companion display. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pGetBrightnessSetting` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_DISPLAY_NOT_ACTIVE - "Display not active" +/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Currently Brightness API is supported only on companion display" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetBrightnessSetting( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_get_brightness_t* pGetBrightnessSetting ///< [out][release] Brightness settings data to be fetched + ); + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_MAX_NUM_SAMPLES_PER_CHANNEL_1D_LUT +/// @brief Maximum number of samples per channel 1D LUT +#define CTL_MAX_NUM_SAMPLES_PER_CHANNEL_1D_LUT 8192 +#endif // CTL_MAX_NUM_SAMPLES_PER_CHANNEL_1D_LUT + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Pixtx pipe set configuration flags bitmasks +typedef uint32_t ctl_pixtx_pipe_set_config_flags_t; +typedef enum _ctl_pixtx_pipe_set_config_flag_t +{ + CTL_PIXTX_PIPE_SET_CONFIG_FLAG_PERSIST_ACROSS_POWER_EVENTS = CTL_BIT(0),///< For maintaining persistance across power events + CTL_PIXTX_PIPE_SET_CONFIG_FLAG_MAX = 0x80000000 + +} ctl_pixtx_pipe_set_config_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Pixel transformation block types +typedef enum _ctl_pixtx_block_type_t +{ + CTL_PIXTX_BLOCK_TYPE_1D_LUT = 1, ///< Block type 1D LUT + CTL_PIXTX_BLOCK_TYPE_3D_LUT = 2, ///< Block type 3D LUT + CTL_PIXTX_BLOCK_TYPE_3X3_MATRIX = 3, ///< Block type 3x3 matrix + CTL_PIXTX_BLOCK_TYPE_3X3_MATRIX_AND_OFFSETS = 4,///< Block type 3x3 matrix and offsets + CTL_PIXTX_BLOCK_TYPE_MAX + +} ctl_pixtx_block_type_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Pixel transformation LUT sampling types +typedef enum _ctl_pixtx_lut_sampling_type_t +{ + CTL_PIXTX_LUT_SAMPLING_TYPE_UNIFORM = 0, ///< Uniform LUT sampling + CTL_PIXTX_LUT_SAMPLING_TYPE_NONUNIFORM = 1, ///< Non uniform LUT sampling, Required mainly in HDR mode + CTL_PIXTX_LUT_SAMPLING_TYPE_MAX + +} ctl_pixtx_lut_sampling_type_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Configuration query types +typedef enum _ctl_pixtx_config_query_type_t +{ + CTL_PIXTX_CONFIG_QUERY_TYPE_CAPABILITY = 0, ///< Get complete pixel processing pipeline capability + CTL_PIXTX_CONFIG_QUERY_TYPE_CURRENT = 1, ///< Get the configuration set through last set call + CTL_PIXTX_CONFIG_QUERY_TYPE_MAX + +} ctl_pixtx_config_query_type_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Configuration operation types +typedef enum _ctl_pixtx_config_opertaion_type_t +{ + CTL_PIXTX_CONFIG_OPERTAION_TYPE_RESTORE_DEFAULT = 1,///< Restore block by block or entire pipe line. Use NumBlocks = 0 to + ///< restore all. + CTL_PIXTX_CONFIG_OPERTAION_TYPE_SET_CUSTOM = 2, ///< Custom LUT or matrix can be set thorugh this option. + CTL_PIXTX_CONFIG_OPERTAION_TYPE_MAX + +} ctl_pixtx_config_opertaion_type_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Pixel transformation gamma encoding types +typedef enum _ctl_pixtx_gamma_encoding_type_t +{ + CTL_PIXTX_GAMMA_ENCODING_TYPE_SRGB = 0, ///< Gamma encoding SRGB + CTL_PIXTX_GAMMA_ENCODING_TYPE_REC709 = 1, ///< Gamma encoding REC709, Applicable for REC2020 as well + CTL_PIXTX_GAMMA_ENCODING_TYPE_ST2084 = 2, ///< Gamma encoding ST2084 + CTL_PIXTX_GAMMA_ENCODING_TYPE_HLG = 3, ///< Gamma encoding HLG + CTL_PIXTX_GAMMA_ENCODING_TYPE_LINEAR = 4, ///< Gamma encoding linear + CTL_PIXTX_GAMMA_ENCODING_TYPE_MAX + +} ctl_pixtx_gamma_encoding_type_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Pixel transformation color space types +typedef enum _ctl_pixtx_color_space_t +{ + CTL_PIXTX_COLOR_SPACE_REC709 = 0, ///< Color space REC709 + CTL_PIXTX_COLOR_SPACE_REC2020 = 1, ///< Color space REC2020 + CTL_PIXTX_COLOR_SPACE_ADOBE_RGB = 2, ///< Color space AdobeRGB + CTL_PIXTX_COLOR_SPACE_P3_D65 = 3, ///< Color space P3_D65 + CTL_PIXTX_COLOR_SPACE_P3_DCI = 4, ///< Color space P3_DCI + CTL_PIXTX_COLOR_SPACE_P3_D60 = 5, ///< Color space P3_D60 + CTL_PIXTX_COLOR_SPACE_CUSTOM = 0xFFFF, ///< Color space custom, Refer ::ctl_pixtx_color_primaries_t for color + ///< primary details + CTL_PIXTX_COLOR_SPACE_MAX + +} ctl_pixtx_color_space_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Pixel transformation color model types +typedef enum _ctl_pixtx_color_model_t +{ + CTL_PIXTX_COLOR_MODEL_RGB_FR = 0, ///< Color model RGB full range + CTL_PIXTX_COLOR_MODEL_RGB_LR = 1, ///< Color model RGB limited range + CTL_PIXTX_COLOR_MODEL_YCBCR_422_FR = 2, ///< Color model YCBCR 422 full range + CTL_PIXTX_COLOR_MODEL_YCBCR_422_LR = 3, ///< Color model YCBCR 422 limited range + CTL_PIXTX_COLOR_MODEL_YCBCR_420_FR = 4, ///< Color model YCBCR 420 full range + CTL_PIXTX_COLOR_MODEL_YCBCR_420_LR = 5, ///< Color model YCBCR 420 limited range + CTL_PIXTX_COLOR_MODEL_YCBCR_444_FR = 6, ///< Color model YCBCR 444 full range + CTL_PIXTX_COLOR_MODEL_YCBCR_444_LR = 7, ///< Color model YCBCR 444 limited range + CTL_PIXTX_COLOR_MODEL_MAX + +} ctl_pixtx_color_model_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Pixel transformation color primaries +typedef struct _ctl_pixtx_color_primaries_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + double xR; ///< [out] CIE1931 x value with maximum red pixel value + double yR; ///< [out] CIE1931 y value with maximum red pixel value + double xG; ///< [out] CIE1931 x value with maximum green pixel value + double yG; ///< [out] CIE1931 y value with maximum green pixel value + double xB; ///< [out] CIE1931 x value with maximum blue pixel value + double yB; ///< [out] CIE1931 y value with maximum blue pixel value + double xW; ///< [out] CIE1931 x value with maximum white pixel value + double yW; ///< [out] CIE1931 y value with maximum white pixel value + +} ctl_pixtx_color_primaries_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Pixel transformation pixel format +typedef struct _ctl_pixtx_pixel_format_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint32_t BitsPerColor; ///< [out] Bits per color, It Will be 16 for FP16 case + bool IsFloat; ///< [out] Will be set for FP16 or other floating point encoding schemes + ctl_pixtx_gamma_encoding_type_t EncodingType; ///< [out] Encoding type + ctl_pixtx_color_space_t ColorSpace; ///< [out] Color space + ctl_pixtx_color_model_t ColorModel; ///< [out] Color model + ctl_pixtx_color_primaries_t ColorPrimaries; ///< [out] Color primaries, Used mainly for custom color space + double MaxBrightness; ///< [out] Maximum brightness of pixel values. If no input is given, + ///< default will be set to sRGB during set call. If panel capability is + ///< not known get call will default to sRGB. + double MinBrightness; ///< [out] Minimum brightness of pixel values + +} ctl_pixtx_pixel_format_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Pixel transformation 1D LUT configuration +typedef struct _ctl_pixtx_1dlut_config_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_pixtx_lut_sampling_type_t SamplingType; ///< [in,out] Blocks with non-uniform sampling capability support unifrom + ///< sampling also but not vice versa. + uint32_t NumSamplesPerChannel; ///< [in,out] Number of samples per channel. Resampled internally based on + ///< HW capability for uniformly sampled LUT.Maximum supported value is + ///< ::CTL_MAX_NUM_SAMPLES_PER_CHANNEL_1D_LUT Caller needs to use exact + ///< sampling position given in pSamplePositions for non-uniformly sampled + ///< LUTs. + uint32_t NumChannels; ///< [in,out] Number of channels, 1 for Grey scale LUT, 3 for RGB LUT + double* pSampleValues; ///< [in,out] Pointer to sample values, R array followed by G and B arrays + ///< in case of multi-channel LUT. Allocation size for pSampleValues should + ///< be NumSamplesPerChannel * NumChannels * sizeof(double) + double* pSamplePositions; ///< [out] LUT (same for all channels) to represent sampling positions for + ///< non-uniformly sampled LUTs.Can be NULL in case uniformly sampled LUTs + +} ctl_pixtx_1dlut_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Pixel transformation matrix configuration +typedef struct _ctl_pixtx_matrix_config_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + double PreOffsets[3]; ///< [in,out] Pre offsets + double PostOffsets[3]; ///< [in,out] Post offsets + double Matrix[3][3]; ///< [in,out] 3x3 Matrix + +} ctl_pixtx_matrix_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Pixel transformation 3D LUT sample. Samples are converted to integer +/// based on underlying HW capabilities. Hence slight precision loss will +/// be observed while getting sample values. +typedef struct _ctl_pixtx_3dlut_sample_t +{ + double Red; ///< [in,out] Red output value + double Green; ///< [in,out] Green output value + double Blue; ///< [in,out] Blue output value + +} ctl_pixtx_3dlut_sample_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Pixel transformation 3D LUT configuration +typedef struct _ctl_pixtx_3dlut_config_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint32_t NumSamplesPerChannel; ///< [in,out] Number of samples per channel + ctl_pixtx_3dlut_sample_t* pSampleValues; ///< [in,out] Pointer to sample values, R in outer most loop followed by G + ///< and B + +} ctl_pixtx_3dlut_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Pixel transformation configuration +typedef union _ctl_pixtx_config_t +{ + ctl_pixtx_1dlut_config_t OneDLutConfig; ///< [in,out] 1D LUT configuration + ctl_pixtx_3dlut_config_t ThreeDLutConfig; ///< [in,out] 3D LUT configuration + ctl_pixtx_matrix_config_t MatrixConfig; ///< [in,out] Matrix configuration + +} ctl_pixtx_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Pixel transformation block configuration +typedef struct _ctl_pixtx_block_config_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint32_t BlockId; ///< [in,out] Unique ID for each pixel processing block. Id for a block is + ///< fixed for a platform. + ctl_pixtx_block_type_t BlockType; ///< [in,out] Block type + ctl_pixtx_config_t Config; ///< [in,out] Configuration + +} ctl_pixtx_block_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Pixel transformation pipe get configuration +typedef struct _ctl_pixtx_pipe_get_config_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_pixtx_config_query_type_t QueryType; ///< [in] Query operation type + ctl_pixtx_pixel_format_t InputPixelFormat; ///< [out] Input pixel format + ctl_pixtx_pixel_format_t OutputPixelFormat; ///< [out] Output pixel format + uint32_t NumBlocks; ///< [out] Number of blocks + ctl_pixtx_block_config_t* pBlockConfigs; ///< [out] Pointer to specific configs + +} ctl_pixtx_pipe_get_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Pixel transformation pipe set configuration +typedef struct _ctl_pixtx_pipe_set_config_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_pixtx_config_opertaion_type_t OpertaionType;///< [in] Set operation type + ctl_pixtx_pipe_set_config_flags_t Flags; ///< [in] Config flags. Refer ::ctl_pixtx_pipe_set_config_flag_t + uint32_t NumBlocks; ///< [in] Number of blocks + ctl_pixtx_block_config_t* pBlockConfigs; ///< [in,out] Array of block specific configs + +} ctl_pixtx_pipe_set_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Pixel transformation get pipe configuration +/// +/// @details +/// - The application does pixel transformation get pipe configuration +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pPixTxGetConfigArgs` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" +/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +/// - ::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 - "Kernal mode driver call failure" +/// - ::CTL_RESULT_ERROR_INVALID_PIXTX_GET_CONFIG_QUERY_TYPE - "Invalid query type" +/// - ::CTL_RESULT_ERROR_INVALID_PIXTX_BLOCK_ID - "Invalid block id" +/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PIXTX_BLOCK_CONFIG_MEMORY - "Insufficient memery allocated for BlockConfigs" +/// - ::CTL_RESULT_ERROR_3DLUT_INVALID_PIPE - "Invalid pipe for 3dlut" +/// - ::CTL_RESULT_ERROR_3DLUT_INVALID_DATA - "Invalid 3dlut data" +/// - ::CTL_RESULT_ERROR_3DLUT_NOT_SUPPORTED_IN_HDR - "3dlut not supported in HDR" +/// - ::CTL_RESULT_ERROR_3DLUT_INVALID_OPERATION - "Invalid 3dlut operation" +/// - ::CTL_RESULT_ERROR_3DLUT_UNSUCCESSFUL - "3dlut call unsuccessful" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlPixelTransformationGetConfig( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_pixtx_pipe_get_config_t* pPixTxGetConfigArgs///< [in,out] Pixel transformation get pipe configiguration arguments + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Pixel transformation set pipe configuration +/// +/// @details +/// - The application does pixel transformation set pipe configuration +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pPixTxSetConfigArgs` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" +/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +/// - ::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 - "Kernal mode driver call failure" +/// - ::CTL_RESULT_ERROR_INVALID_PIXTX_SET_CONFIG_OPERATION_TYPE - "Invalid operation type" +/// - ::CTL_RESULT_ERROR_INVALID_SET_CONFIG_NUMBER_OF_SAMPLES - "Invalid number of samples" +/// - ::CTL_RESULT_ERROR_INVALID_PIXTX_BLOCK_ID - "Invalid block id" +/// - ::CTL_RESULT_ERROR_PERSISTANCE_NOT_SUPPORTED - "Persistance not supported" +/// - ::CTL_RESULT_ERROR_3DLUT_INVALID_PIPE - "Invalid pipe for 3dlut" +/// - ::CTL_RESULT_ERROR_3DLUT_INVALID_DATA - "Invalid 3dlut data" +/// - ::CTL_RESULT_ERROR_3DLUT_NOT_SUPPORTED_IN_HDR - "3dlut not supported in HDR" +/// - ::CTL_RESULT_ERROR_3DLUT_INVALID_OPERATION - "Invalid 3dlut operation" +/// - ::CTL_RESULT_ERROR_3DLUT_UNSUCCESSFUL - "3dlut call unsuccessful" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlPixelTransformationSetConfig( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_pixtx_pipe_set_config_t* pPixTxSetConfigArgs///< [in,out] Pixel transformation set pipe configiguration arguments + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Panel descriptor access arguments +typedef struct _ctl_panel_descriptor_access_args_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_operation_type_t OpType; ///< [in] Operation type, 1 for Read, 2 for Write. App needs to run with + ///< admin privileges for Write operation, Currently only Read operation is + ///< supported + uint32_t BlockNumber; ///< [in] Block number, Need to provide only if acccessing EDID + uint32_t DescriptorDataSize; ///< [in] Descriptor data size, Should be 0 for querying the size and + ///< should be DescriptorDataSize derived from query call otherwise + uint8_t* pDescriptorData; ///< [in,out] Panel descriptor data + +} ctl_panel_descriptor_access_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Panel Descriptor Access +/// +/// @details +/// - The application does EDID or Display ID access +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pPanelDescriptorAccessArgs` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" +/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" +/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +/// - ::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 - "Kernal mode driver call failure" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlPanelDescriptorAccess( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_panel_descriptor_access_args_t* pPanelDescriptorAccessArgs ///< [in,out] Panel descriptor access arguments + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Retro Scaling Types +typedef uint32_t ctl_retro_scaling_type_flags_t; +typedef enum _ctl_retro_scaling_type_flag_t +{ + CTL_RETRO_SCALING_TYPE_FLAG_INTEGER = CTL_BIT(0), ///< Integer Scaling + CTL_RETRO_SCALING_TYPE_FLAG_NEAREST_NEIGHBOUR = CTL_BIT(1), ///< Nearest Neighbour Scaling + CTL_RETRO_SCALING_TYPE_FLAG_MAX = 0x80000000 + +} ctl_retro_scaling_type_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set/Get Retro Scaling Type +typedef struct _ctl_retro_scaling_settings_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + bool Get; ///< [in][release] Set to true to get current scaling . Set to False to Set + ///< the scaling + bool Enable; ///< [in,out] State of the scaler + ctl_retro_scaling_type_flags_t RetroScalingType;///< [out] Requested retro scaling types. Refer + ///< ::ctl_retro_scaling_type_flag_t + +} ctl_retro_scaling_settings_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Retro Scaling caps +typedef struct _ctl_retro_scaling_caps_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_retro_scaling_type_flags_t SupportedRetroScaling; ///< [out] Supported retro scaling types + +} ctl_retro_scaling_caps_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Supported Retro Scaling Types +/// +/// @details +/// - Returns supported retro scaling capabilities +/// +/// @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 == pRetroScalingCaps` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetSupportedRetroScalingCapability( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to adapter + ctl_retro_scaling_caps_t* pRetroScalingCaps ///< [in,out][release] Query result for supported retro scaling types + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get/Set Retro Scaling +/// +/// @details +/// - Get or Set the status of retro scaling.This Api will do a physical +/// modeset resulting in flash on the screen +/// +/// @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 == pGetSetRetroScalingType` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetSetRetroScaling( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to adapter + ctl_retro_scaling_settings_t* pGetSetRetroScalingType ///< [in,out][release] Get or Set the retro scaling type + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Scaling Types +typedef uint32_t ctl_scaling_type_flags_t; +typedef enum _ctl_scaling_type_flag_t +{ + CTL_SCALING_TYPE_FLAG_IDENTITY = CTL_BIT(0), ///< No scaling is applied and display manages scaling itself when possible + CTL_SCALING_TYPE_FLAG_CENTERED = CTL_BIT(1), ///< Source is not scaled but place in the center of the target display + CTL_SCALING_TYPE_FLAG_STRETCHED = CTL_BIT(2), ///< Source is stretched to fit the target size + CTL_SCALING_TYPE_FLAG_ASPECT_RATIO_CENTERED_MAX = CTL_BIT(3), ///< The aspect ratio is maintained with the source centered + CTL_SCALING_TYPE_FLAG_CUSTOM = CTL_BIT(4), ///< None of the standard types match this .Additional parameters are + ///< required which should be set via a private driver interface + CTL_SCALING_TYPE_FLAG_MAX = 0x80000000 + +} ctl_scaling_type_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Scaling caps +typedef struct _ctl_scaling_caps_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_scaling_type_flags_t SupportedScaling; ///< [out] Supported scaling types. Refer ::ctl_scaling_type_flag_t + +} ctl_scaling_caps_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set/Get Scaling type +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 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; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Supported Scaling Types +/// +/// @details +/// - Returns supported scaling capabilities +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pScalingCaps` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetSupportedScalingCapability( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_scaling_caps_t* pScalingCaps ///< [in,out][release] Query result for supported scaling types + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Current Scaling +/// +/// @details +/// - Returns current active scaling +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pGetCurrentScalingType` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetCurrentScaling( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_scaling_settings_t* pGetCurrentScalingType ///< [in,out][release] Query result for active scaling types + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set Scaling Type +/// +/// @details +/// - Returns current active scaling +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pSetScalingType` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlSetCurrentScaling( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_scaling_settings_t* pSetScalingType ///< [in,out][release] Set scaling types + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Ambient light based enhancement table entry +typedef struct _ctl_lace_lux_aggr_map_entry_t +{ + uint32_t Lux; ///< [in,out] Ambient lux + uint8_t AggressivenessPercent; ///< [in,out] Pixel boost agressiveness + +} ctl_lace_lux_aggr_map_entry_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Ambient light based enhancement table +typedef struct _ctl_lace_lux_aggr_map_t +{ + uint32_t MaxNumEntries; ///< [out] Max Number of entries in mapping table supported + uint32_t NumEntries; ///< [in,out] Number of entries in the given mapping table + ctl_lace_lux_aggr_map_entry_t* pLuxToAggrMappingTable; ///< [in] Max number of Entries which can be passed in + ///< LuxToAggrMappingTable + +} ctl_lace_lux_aggr_map_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Data specific to the mode caller is interested in +typedef union _ctl_lace_aggr_config_t +{ + uint8_t FixedAggressivenessLevelPercent; ///< [in,out] Fixed aggressiveness level, applicable for + ///< CTL_LACE_MODE_FIXED_AGGR_LEVEL + ctl_lace_lux_aggr_map_t AggrLevelMap; ///< [in,out] Lux to enhancement mapping table, applicable for + ///< CTL_LACE_MODE_AMBIENT_ADAPTIVE + +} ctl_lace_aggr_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Operations used for additional settings +typedef uint32_t ctl_get_operation_flags_t; +typedef enum _ctl_get_operation_flag_t +{ + CTL_GET_OPERATION_FLAG_CURRENT = CTL_BIT(0), ///< Get the details set through last set call + CTL_GET_OPERATION_FLAG_DEFAULT = CTL_BIT(1), ///< Get the driver default values + CTL_GET_OPERATION_FLAG_CAPABILITY = CTL_BIT(2), ///< Get capability + CTL_GET_OPERATION_FLAG_MAX = 0x80000000 + +} ctl_get_operation_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set Operations used for additional settings +typedef enum _ctl_set_operation_t +{ + CTL_SET_OPERATION_RESTORE_DEFAULT = 0, ///< Restore default values + CTL_SET_OPERATION_CUSTOM = 1, ///< Set custom values + CTL_SET_OPERATION_MAX + +} ctl_set_operation_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Lace Trigger Modes +typedef uint32_t ctl_lace_trigger_flags_t; +typedef enum _ctl_lace_trigger_flag_t +{ + CTL_LACE_TRIGGER_FLAG_AMBIENT_LIGHT = CTL_BIT(0), ///< LACE enhancement depends on Ambient light + CTL_LACE_TRIGGER_FLAG_FIXED_AGGRESSIVENESS = CTL_BIT(1),///< LACE enhancement is as per given fixed aggressiveness level + CTL_LACE_TRIGGER_FLAG_MAX = 0x80000000 + +} ctl_lace_trigger_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set/Get LACE Config +typedef struct _ctl_lace_config_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + bool Enabled; ///< [in,out] Enable or disable LACE feature + ctl_get_operation_flags_t OpTypeGet; ///< [in] Get Operations used for additional settings + ctl_set_operation_t OpTypeSet; ///< [in] Set Operations used for additional settings + ctl_lace_trigger_flags_t Trigger; ///< [in,out] LACE operating mode to be Triggerd + ctl_lace_aggr_config_t LaceConfig; ///< [in,out] Data specific to the mode, caller is interested in + +} ctl_lace_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get LACE Config +/// +/// @details +/// - Returns current LACE Config +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pLaceConfig` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_LACE_INVALID_DATA_ARGUMENT_PASSED - "Lace Incorrrect AggressivePercent data or LuxVsAggressive Map data passed by user" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetLACEConfig( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_lace_config_t* pLaceConfig ///< [out]Lace configuration + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Sets LACE Config +/// +/// @details +/// - Sets LACE Config +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pLaceConfig` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_LACE_INVALID_DATA_ARGUMENT_PASSED - "Lace Incorrrect AggressivePercent data or LuxVsAggressive Map data passed by user" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlSetLACEConfig( + ctl_display_output_handle_t hDisplayOutput, ///< [in]Handle to display output + ctl_lace_config_t* pLaceConfig ///< [in]Lace configuration + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Software PSR status/Set Software PSR settings +typedef struct _ctl_sw_psr_settings_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + bool Set; ///< [in][release] Set to False to Get Software PSR status. Set to True to + ///< Enable/Disable Software PSR + bool Supported; ///< [out] When Get is True, returns if SW PSR is supported + bool Enable; ///< [in,out] When Get is True, returns current state of Software PSR. + ///< When Get is False, Enables/Diasbles Software PSR + +} ctl_sw_psr_settings_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Software PSR caps/Set software PSR State +/// +/// @details +/// - Returns Software PSR status or Sets Software PSR capabilities. This is +/// a reserved capability. By default, software PSR is not supported/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 == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pSoftwarePsrSetting` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlSoftwarePSR( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_sw_psr_settings_t* pSoftwarePsrSetting ///< [in,out][release] Get Software PSR caps/state or Set Software PSR + ///< state + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intel Arc Sync Monitor Params +typedef struct _ctl_intel_arc_sync_monitor_params_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + bool IsIntelArcSyncSupported; ///< [out] Intel Arc Sync support for the monitor + float MinimumRefreshRateInHz; ///< [out] Minimum Intel Arc Sync refresh rate supported by the monitor + float MaximumRefreshRateInHz; ///< [out] Maximum Intel Arc Sync refresh rate supported by the monitor + uint32_t MaxFrameTimeIncreaseInUs; ///< [out] Max frame time increase in micro seconds from DID2.1 Adaptive + ///< Sync block + uint32_t MaxFrameTimeDecreaseInUs; ///< [out] Max frame time decrease in micro seconds from DID2.1 Adaptive + ///< Sync block + +} ctl_intel_arc_sync_monitor_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Intel Arc Sync information for monitor +/// +/// @details +/// - Returns Intel Arc Sync information for selected monitor +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pIntelArcSyncMonitorParams` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetIntelArcSyncInfoForMonitor( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_intel_arc_sync_monitor_params_t* pIntelArcSyncMonitorParams ///< [in,out][release] Intel Arc Sync params for monitor + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intel Arc Sync profile +typedef enum _ctl_intel_arc_sync_profile_t +{ + CTL_INTEL_ARC_SYNC_PROFILE_INVALID = 0, ///< Invalid profile + CTL_INTEL_ARC_SYNC_PROFILE_RECOMMENDED = 1, ///< Default. Selects appropriate profile based on the monitor. COMPATIBLE + ///< profile is applied if profile is not available for the monitor + CTL_INTEL_ARC_SYNC_PROFILE_EXCELLENT = 2, ///< Unconstrained. Full VRR range of the monitor can be used + CTL_INTEL_ARC_SYNC_PROFILE_GOOD = 3, ///< Some minor range constraints, unlikely to effect user experience but + ///< can reduce flicker on some monitors + CTL_INTEL_ARC_SYNC_PROFILE_COMPATIBLE = 4, ///< Significant constraints that will reduce flicker considerably but are + ///< likely to cause some level of judder onscreen especially when refresh + ///< rates are changing rapidly + CTL_INTEL_ARC_SYNC_PROFILE_OFF = 5, ///< Disable Intel Arc Sync on this monitor. This disables variable rate + ///< flips on this monitor. All sync flips will occur at the OS requested + ///< refresh rate + CTL_INTEL_ARC_SYNC_PROFILE_VESA = 6, ///< Applies vesa specified constraints if the monitor has provided them, + ///< COMPATIBLE profile if not + CTL_INTEL_ARC_SYNC_PROFILE_CUSTOM = 7, ///< Unlocks controls to set a custom Intel Arc Sync profile + CTL_INTEL_ARC_SYNC_PROFILE_MAX + +} ctl_intel_arc_sync_profile_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Intel Arc Sync Profile Params +typedef struct _ctl_intel_arc_sync_profile_params_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_intel_arc_sync_profile_t IntelArcSyncProfile; ///< [in,out] Intel Arc Sync profile used by driver. Refer + ///< ::ctl_intel_arc_sync_profile_t + float MaxRefreshRateInHz; ///< [in,out] Maximum refresh rate utilized by the driver + float MinRefreshRateInHz; ///< [in,out] Minimum refresh rate utilized by the driver + uint32_t MaxFrameTimeIncreaseInUs; ///< [in,out] Maximum frame time increase (in micro seconds) imposed by the + ///< driver + uint32_t MaxFrameTimeDecreaseInUs; ///< [in,out] Maximum frame time decrease (in micro seconds) imposed by the + ///< driver + +} ctl_intel_arc_sync_profile_params_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Intel Arc Sync profile +/// +/// @details +/// - Returns Intel Arc Sync profile for selected monitor +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pIntelArcSyncProfileParams` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetIntelArcSyncProfile( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_intel_arc_sync_profile_params_t* pIntelArcSyncProfileParams ///< [in,out][release] Intel Arc Sync params for monitor + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set Intel Arc Sync profile +/// +/// @details +/// - Sets Intel Arc Sync profile for selected monitor. In a mux situation, +/// this API should be called for all display IDs associated with a +/// physical display. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pIntelArcSyncProfileParams` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlSetIntelArcSyncProfile( + ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output + ctl_intel_arc_sync_profile_params_t* pIntelArcSyncProfileParams ///< [in][release] Intel Arc Sync params for monitor + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief EDID Management operation type +typedef enum _ctl_edid_management_optype_t +{ + CTL_EDID_MANAGEMENT_OPTYPE_READ_EDID = 1, ///< This operation type is to read an output's EDID. Set edid_type input + ///< arg to read MONITOR EDID or previously OVERRIDDEN EDID or CURRENT + ///< active EDID. Read EDID is a 2 pass call. First call with size = 0, + ///< pEdidBuf = nullptr to get the size, then call with allocated buffer to + ///< get the EDID data. READ operation is applicable for any normal, edid + ///< locked or edid overridden display output device. + CTL_EDID_MANAGEMENT_OPTYPE_LOCK_EDID = 2, ///< To make an output always connected with OVERRIDE or MONITOR EDID + ///< across reboots. When output isn't connected call with OVERRIDE EDID; + ///< when connected, either set OVERRIDE and provide pEdidBuf or set + ///< MONITOR and driver will use monitor's EDID. There is no change to EDID + ///< stored in Monitor. Cannot be called when override is active. Any OS + ///< EDID override will take precedence over IGCL override. + CTL_EDID_MANAGEMENT_OPTYPE_UNLOCK_EDID = 3, ///< To undo lock EDID operation, i.e. it makes output as detached in + ///< response to unplug. This operation removes past supplied EDID; output + ///< status is reported to OS as it is; output restores back to monitor's + ///< EDID when it is connected + CTL_EDID_MANAGEMENT_OPTYPE_OVERRIDE_EDID = 4, ///< To replace an output's EDID with supplied one (pEdidBuf) only when + ///< physical display is connected. There is no change to EDID stored in + ///< Monitor. Cannot apply this operation on locked output. When no output + ///< device attached, the supplied EDID will be persisted in driver for + ///< future use. Any OS EDID override will take precedence over IGCL + ///< override. + CTL_EDID_MANAGEMENT_OPTYPE_UNDO_OVERRIDE_EDID = 5, ///< To undo override EDID operation, that is remove previously overridden + ///< EDID on an output. Output restores back to monitor's EDID when it is + ///< connected + CTL_EDID_MANAGEMENT_OPTYPE_MAX + +} ctl_edid_management_optype_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief EDID type. Used in LOCK_EDID and READ_EDID calls. +typedef enum _ctl_edid_type_t +{ + CTL_EDID_TYPE_CURRENT = 1, ///< [in] Used to return currently active EDID in READ_EDID call. + CTL_EDID_TYPE_OVERRIDE = 2, ///< [in] Is it user supplied EDID. Used in LOCK_EDID call with Supplied + ///< EDID or in READ_EDID to get Supplied EDID. + CTL_EDID_TYPE_MONITOR = 3, ///< [in] Is it Monitor's EDID. Used in LOCK_EDID and READ_EDID calls. + CTL_EDID_TYPE_MAX + +} ctl_edid_type_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Edid management operation Out Flags +typedef uint32_t ctl_edid_management_out_flags_t; +typedef enum _ctl_edid_management_out_flag_t +{ + CTL_EDID_MANAGEMENT_OUT_FLAG_OS_CONN_NOTIFICATION = CTL_BIT(0), ///< [out] If OS was notified about a connection change. App will need to + ///< wait for the OS action to complete. + CTL_EDID_MANAGEMENT_OUT_FLAG_SUPPLIED_EDID = CTL_BIT(1),///< [out] Is it previously supplied EDID, set for READ_EDID(CURRENT). + CTL_EDID_MANAGEMENT_OUT_FLAG_MONITOR_EDID = CTL_BIT(2), ///< [out] Is it Monitor's EDID, set for READ_EDID(CURRENT). + CTL_EDID_MANAGEMENT_OUT_FLAG_DISPLAY_CONNECTED = CTL_BIT(3),///< [out] Is Monitor physically connected + CTL_EDID_MANAGEMENT_OUT_FLAG_MAX = 0x80000000 + +} ctl_edid_management_out_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief EDID management +typedef struct _ctl_edid_management_args_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_edid_management_optype_t OpType; ///< [in] EDID managmeent operation type + ctl_edid_type_t EdidType; ///< [in] EDID Type, Monitor or Supplied + uint32_t EdidSize; ///< [in,out] EDID Size, should be 0 for querying the size of EDID, should + ///< be previously returned size to read EDID. if buffer isn't big enough + ///< to fit EDID, returns size of EDID bytes. + uint8_t* pEdidBuf; ///< [in,out] buffer holding EDID data + ctl_edid_management_out_flags_t OutFlags; ///< [out] Output flags to inform about status of EDID management + ///< operations + +} ctl_edid_management_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief EDID Management allows managing an output's EDID or Plugged Status. +/// +/// @details +/// - To manage output's EDID or Display ID. Supports native DP SST and HDMI +/// Display types. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pEdidManagementArgs` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" +/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +/// - ::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 - "Kernal mode driver call failure" +/// - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid combination of parameters" +/// - ::CTL_RESULT_ERROR_DISPLAY_NOT_ATTACHED - "Error for Output Device not attached" +/// - ::CTL_RESULT_ERROR_OUT_OF_DEVICE_MEMORY - "Insufficient device memory to satisfy call" +/// - ::CTL_RESULT_ERROR_DATA_NOT_FOUND - "Requested EDID data not present." +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlEdidManagement( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_edid_management_args_t* pEdidManagementArgs ///< [in,out] EDID management arguments + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Custom mode operation types +typedef enum _ctl_custom_mode_operation_types_t +{ + CTL_CUSTOM_MODE_OPERATION_TYPES_GET_CUSTOM_SOURCE_MODES = 0,///< Get details of all previous applied custom modes if any. + CTL_CUSTOM_MODE_OPERATION_TYPES_ADD_CUSTOM_SOURCE_MODE = 1, ///< Add a new mode. Allows only single mode adition at a time. + CTL_CUSTOM_MODE_OPERATION_TYPES_REMOVE_CUSTOM_SOURCE_MODES = 2, ///< Remove previously added custom mode. Allows single or multiple mode + ///< removal at a time. + CTL_CUSTOM_MODE_OPERATION_TYPES_MAX + +} ctl_custom_mode_operation_types_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get/Set Custom Mode +typedef struct _ctl_get_set_custom_mode_args_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_custom_mode_operation_types_t CustomModeOpType; ///< [in] Custom mode operation type + uint32_t NumOfModes; ///< [in,out] Number of Custom Src Modes to be added/removed/Read. + ctl_custom_src_mode_t* pCustomSrcModeList; ///< [in,out] Custom mode source list which holds source modes to be + ///< added/removed/Read. + +} ctl_get_set_custom_mode_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get/Set Custom Mode +typedef struct _ctl_custom_src_mode_t +{ + uint32_t SourceX; ///< [in,out] CustomMode Source X Size + uint32_t SourceY; ///< [in,out] CustomMode Source Y Size + +} ctl_custom_src_mode_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get/Set Custom mode. +/// +/// @details +/// - To get or set custom mode. +/// - Add custom source mode operation supports only single mode additon at +/// a time. +/// - Remove custom source mode operation supports single or multiple mode +/// removal at a time. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pCustomModeArgs` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" +/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +/// - ::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 - "Kernal mode driver call failure" +/// - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid combination of parameters" +/// - ::CTL_RESULT_ERROR_CUSTOM_MODE_STANDARD_CUSTOM_MODE_EXISTS - "Standard custom mode exists" +/// - ::CTL_RESULT_ERROR_CUSTOM_MODE_NON_CUSTOM_MATCHING_MODE_EXISTS - "Non custom matching mode exists" +/// - ::CTL_RESULT_ERROR_CUSTOM_MODE_INSUFFICIENT_MEMORY - "Custom mode insufficent memory" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetSetCustomMode( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_get_set_custom_mode_args_t* pCustomModeArgs ///< [in,out] Custom mode arguments + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Combined Display operation type +typedef enum _ctl_combined_display_optype_t +{ + CTL_COMBINED_DISPLAY_OPTYPE_IS_SUPPORTED_CONFIG = 1,///< To check whether given outputs can form a combined display, no changes + ///< are applied + CTL_COMBINED_DISPLAY_OPTYPE_ENABLE = 2, ///< To setup and enable a combined display + CTL_COMBINED_DISPLAY_OPTYPE_DISABLE = 3, ///< To disable combined display + CTL_COMBINED_DISPLAY_OPTYPE_QUERY_CONFIG = 4, ///< To query combined display configuration + CTL_COMBINED_DISPLAY_OPTYPE_MAX + +} ctl_combined_display_optype_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Combined Display's child display target mode +typedef struct _ctl_child_display_target_mode_t +{ + uint32_t Width; ///< [in,out] Width + uint32_t Height; ///< [in,out] Height + float RefreshRate; ///< [in,out] Refresh Rate + uint32_t ReservedFields[4]; ///< [out] Reserved field of 16 bytes + +} ctl_child_display_target_mode_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Combined Display's child display information +typedef struct _ctl_combined_display_child_info_t +{ + ctl_display_output_handle_t hDisplayOutput; ///< [in,out] Display output handle under combined display configuration + ctl_rect_t FbSrc; ///< [in,out] FrameBuffer source's RECT within Combined Display respective + ctl_rect_t FbPos; ///< [in,out] FrameBuffer target's RECT within output size + ctl_display_orientation_t DisplayOrientation; ///< [in,out] 0/180 Degree Display orientation (rotation) + ctl_child_display_target_mode_t TargetMode; ///< [in,out] Desired target mode (width, height, refresh) + +} ctl_combined_display_child_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Combined Display arguments +typedef struct _ctl_combined_display_args_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_combined_display_optype_t OpType; ///< [in] Combined display operation type + bool IsSupported; ///< [out] Returns yes/no in response to IS_SUPPORTED_CONFIG command + uint8_t NumOutputs; ///< [in,out] Number of outputs part of desired combined display + ///< configuration + uint32_t CombinedDesktopWidth; ///< [in,out] Width of desired combined display configuration + uint32_t CombinedDesktopHeight; ///< [in,out] Height of desired combined display configuration + ctl_combined_display_child_info_t* pChildInfo; ///< [in,out] List of child display information respective to each output. + ///< Up to 16 displays are supported with up to 4 displays per GPU. + ctl_display_output_handle_t hCombinedDisplayOutput; ///< [in,out] Handle to combined display output + +} ctl_combined_display_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get/Set Combined Display +/// +/// @details +/// - To get or set combined display with given Child Targets on a Single +/// GPU or across identical GPUs. Multi-GPU(MGPU) combined display is +/// reserved i.e. it is not public and requires special application GUID. +/// MGPU Combined Display will get activated or deactivated in next boot. +/// MGPU scenario will internally link the associated adapters via Linked +/// Display Adapter Call, with supplied hDeviceAdapter being the LDA +/// Primary. If Genlock and enabled in Driver registry and supported by +/// given Display Config, MGPU Combined Display will enable MGPU Genlock +/// with supplied hDeviceAdapter being the Genlock Primary Adapter and the +/// First Child Display being the Primary Display. +/// +/// @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 == pCombinedDisplayArgs` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" +/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" +/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +/// - ::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_FEATURE_NOT_SUPPORTED - "Combined Display feature is not supported in this platform" +/// - ::CTL_RESULT_ERROR_ADAPTER_NOT_SUPPORTED_ON_LDA_SECONDARY - "Unsupported (secondary) adapter handle passed" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetSetCombinedDisplay( + ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] Handle to control device adapter + ctl_combined_display_args_t* pCombinedDisplayArgs ///< [in,out] Setup and get combined display arguments + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Display Genlock Operations +typedef enum _ctl_genlock_operation_t +{ + CTL_GENLOCK_OPERATION_GET_TIMING_DETAILS = 0, ///< Get details of GENLOCK support and timing information + CTL_GENLOCK_OPERATION_VALIDATE = 1, ///< Driver to verify that the topology is Genlock capable + CTL_GENLOCK_OPERATION_ENABLE = 2, ///< Enable GENLOCK + CTL_GENLOCK_OPERATION_DISABLE = 3, ///< Disable GENLOCK + CTL_GENLOCK_OPERATION_GET_TOPOLOGY = 4, ///< Get details of the current Genlock topology that is applied + CTL_GENLOCK_OPERATION_MAX + +} ctl_genlock_operation_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Display Genlock Info +typedef struct _ctl_genlock_display_info_t +{ + ctl_display_output_handle_t hDisplayOutput; ///< [in,out] Display output handle under Genlock topology + bool IsPrimary; ///< [in,out] Genlock Primary + +} ctl_genlock_display_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Genlock Target Mode List +typedef struct _ctl_genlock_target_mode_list_t +{ + ctl_display_output_handle_t hDisplayOutput; ///< [in] Display output handle for whom target mode list is required + uint32_t NumModes; ///< [in,out] Number of supported Modes that is returned from a driver + ctl_display_timing_t* pTargetModes; ///< [out] Display Genlock operation and information + +} ctl_genlock_target_mode_list_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Genlock Topology +typedef struct _ctl_genlock_topology_t +{ + uint8_t NumGenlockDisplays; ///< [in,out] Number of Genlock displays + bool IsPrimaryGenlockSystem; ///< [in,out] Primary Genlock system + ctl_display_timing_t CommonTargetMode; ///< [in] Common target mode + ctl_genlock_display_info_t* pGenlockDisplayInfo;///< [in,out] List of Genlock display info + ctl_genlock_target_mode_list_t* pGenlockModeList; ///< [out] List of Genlock target modes + +} ctl_genlock_topology_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Display Genlock Arg type +typedef struct _ctl_genlock_args_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_genlock_operation_t Operation; ///< [in] Display Genlock Operation + ctl_genlock_topology_t GenlockTopology; ///< [in,out] Display Genlock array of topology structures + bool IsGenlockEnabled; ///< [out] Whether the feature is currently enabled or not + bool IsGenlockPossible; ///< [out] Indicates if Genlock can be enabled/disabled with the given + ///< topology + +} ctl_genlock_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get/Set Display Genlock +/// +/// @details +/// - To get or set Display Genlock. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == hDeviceAdapter` +/// + `nullptr == pGenlockArgs` +/// + `nullptr == hFailureDeviceAdapter` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +/// - ::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_INVALID_SIZE - "Invalid topology structure size" +/// - ::CTL_RESULT_ERROR_KMD_CALL - "Kernel mode driver call failure" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetSetDisplayGenlock( + ctl_device_adapter_handle_t* hDeviceAdapter, ///< [in][release] Handle to control device adapter + ctl_genlock_args_t* pGenlockArgs, ///< [in,out] Display Genlock operation and information + uint32_t AdapterCount, ///< [in] Number of device adapters + ctl_device_adapter_handle_t* hFailureDeviceAdapter ///< [out] Handle to address the failure device adapter in an error case + ); + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_MAX_DISPLAYS_FOR_MGPU_COLLAGE +/// @brief Maximum number of displays for Single Large Screen +#define CTL_MAX_DISPLAYS_FOR_MGPU_COLLAGE 16 +#endif // CTL_MAX_DISPLAYS_FOR_MGPU_COLLAGE + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Vblank timestamp arguments +typedef struct _ctl_vblank_ts_args_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint8_t NumOfTargets; ///< [out] Number of child targets + uint64_t VblankTS[CTL_MAX_DISPLAYS_FOR_MGPU_COLLAGE]; ///< [out] List of vblank timestamps in microseconds per child target + +} ctl_vblank_ts_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Vblank Timestamp +/// +/// @details +/// - To get a list of vblank timestamps in microseconds for each child +/// target of a display. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pVblankTSArgs` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" +/// - ::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_APIEXPORT ctl_result_t CTL_APICALL +ctlGetVblankTimestamp( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + ctl_vblank_ts_args_t* pVblankTSArgs ///< [out] Get vblank timestamp arguments + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Link Display Adapters Arguments +typedef struct _ctl_lda_args_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint8_t NumAdapters; ///< [in,out] Numbers of adapters to be linked. Up to 4 adapters are + ///< supported + ctl_device_adapter_handle_t* hLinkedAdapters; ///< [in,out][release] List of Control device adapter handles to be linked, + ///< first one being Primary Adapter + uint64_t Reserved[4]; ///< [out] Reserved fields. Set to zero. + +} ctl_lda_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Link Display Adapters +/// +/// @details +/// - To Link Display Adapters. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hPrimaryAdapter` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pLdaArgs` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +/// - ::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_ADAPTER_ALREADY_LINKED - "Adapter is already linked" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlLinkDisplayAdapters( + ctl_device_adapter_handle_t hPrimaryAdapter, ///< [in][release] Handle to Primary adapter in LDA chain + ctl_lda_args_t* pLdaArgs ///< [in] Link Display Adapters Arguments + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Unlink Display Adapters +/// +/// @details +/// - To Unlink Display Adapters +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hPrimaryAdapter` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::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_ADAPTER_NOT_SUPPORTED_ON_LDA_SECONDARY - "Unsupported (secondary) adapter handle passed" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlUnlinkDisplayAdapters( + ctl_device_adapter_handle_t hPrimaryAdapter ///< [in][release] Handle to Primary adapter in LDA chain + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get Linked Display Adapters +/// +/// @details +/// - To return list of Linked Display Adapters. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hPrimaryAdapter` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pLdaArgs` +/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" +/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" +/// - ::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_ADAPTER_NOT_SUPPORTED_ON_LDA_SECONDARY - "Unsupported (secondary) adapter handle passed" +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlGetLinkedDisplayAdapters( + ctl_device_adapter_handle_t hPrimaryAdapter, ///< [in][release] Handle to Primary adapter in LDA chain + ctl_lda_args_t* pLdaArgs ///< [out] Link Display Adapters Arguments + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get/Set Dynamic Contrast Enhancement arguments +typedef struct _ctl_dce_args_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 + uint32_t TargetBrightnessPercent; ///< [in] Target brightness percent + double PhaseinSpeedMultiplier; ///< [in] Phase-in speed multiplier for brightness to take effect + uint32_t NumBins; ///< [in,out] Number of histogram bins + bool Enable; ///< [in,out] For get calls, this represents current state & for set this + ///< represents future state + bool IsSupported; ///< [out] is DCE feature supported + uint32_t* pHistogram; ///< [out] Bin wise histogram data of size NumBins * sizeof(uint32_t) for + ///< current frame + +} ctl_dce_args_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get/Set Dynamic Contrast Enhancement +/// +/// @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 +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pDceArgs` +/// - ::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 +ctlGetSetDynamicContrastEnhancement( + ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output + 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; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Operation type +typedef enum _ctl_wire_format_operation_type_t +{ + 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_wire_format_operation_type_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_wire_format_color_model_t ColorModel; ///< [in,out] Color model + ctl_output_bpc_flags_t ColorDepth; ///< [in,out] Color Depth + +} ctl_wire_format_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 + 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_get_set_wire_format_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get/Set Color Format and Color Depth +/// +/// @details +/// - 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 == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `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 +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 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 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 +/// - 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 == hDisplayOutput` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `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 +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 // display +#endif +// Intel 'ctlApi' for Device Adapter - ECC +#if !defined(__GNUC__) +#pragma region ecc +#endif +/////////////////////////////////////////////////////////////////////////////// +/// @brief ECC properties. +typedef struct _ctl_ecc_properties_t +{ + 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_ecc_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief ECC state. +typedef enum _ctl_ecc_state_t +{ + 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_ecc_state_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 + 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_ecc_state_desc_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @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 + +} ctl_fan_temp_speed_t; + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_FAN_TEMP_SPEED_PAIR_COUNT +/// @brief Maximum number of fan temperature/speed pairs in the fan speed table. +#define CTL_FAN_TEMP_SPEED_PAIR_COUNT 32 +#endif // CTL_FAN_TEMP_SPEED_PAIR_COUNT + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Fan speed table +typedef struct _ctl_fan_speed_table_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + int32_t numPoints; ///< [in,out] The number of valid points in the fan speed table. 0 means + ///< that there is no fan speed table configured. -1 means that a fan speed + ///< table is not supported by the hardware. + ctl_fan_temp_speed_t table[CTL_FAN_TEMP_SPEED_PAIR_COUNT]; ///< [in,out] Array of temperature/fan speed pairs. The table is ordered + ///< based on temperature from lowest to highest. + +} ctl_fan_speed_table_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Fan properties +typedef struct _ctl_fan_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 fan speed assuming the + ///< user has permissions + uint32_t supportedModes; ///< [out] Bitfield of supported fan configuration modes + ///< (1<<::ctl_fan_speed_mode_t) + uint32_t supportedUnits; ///< [out] Bitfield of supported fan speed units + ///< (1<<::ctl_fan_speed_units_t) + int32_t maxRPM; ///< [out] The maximum RPM of the fan. A value of -1 means that this + ///< property is unknown. + int32_t maxPoints; ///< [out] The maximum number of points in the fan temp/speed table. A + ///< value of -1 means that this fan doesn't support providing a temp/speed + ///< table. + +} ctl_fan_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Fan configuration +typedef struct _ctl_fan_config_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_fan_speed_mode_t mode; ///< [in,out] The fan speed mode (fixed, temp-speed table) + ctl_fan_speed_t speedFixed; ///< [in,out] The current fixed fan speed setting + ctl_fan_speed_table_t speedTable; ///< [out] A table containing temperature/speed pairs + +} ctl_fan_config_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get handle of fans +/// +/// @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 +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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get fan 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 == hFan` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pProperties` +CTL_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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. +/// - 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 == hFan` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pConfig` +CTL_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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. +/// - 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 == hFan` +/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS +/// + User does not have permissions to make these modifications. +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlFanSetDefaultMode( + ctl_fan_handle_t hFan ///< [in] Handle for the component. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Configure the fan to rotate at a fixed speed (set mode to +/// ::CTL_FAN_SPEED_MODE_FIXED) +/// +/// @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 == hFan` +/// - 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. +CTL_APIEXPORT 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 + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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. +/// - 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 == hFan` +/// - 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. +CTL_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get current state of a fan - current mode and speed +/// +/// @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 == 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. +CTL_APIEXPORT ctl_result_t CTL_APICALL +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. + ); + + +#if !defined(__GNUC__) +#pragma endregion // fan +#endif +// Intel 'ctlApi' for Device Adapter - Firmware management +#if !defined(__GNUC__) +#pragma region firmware +#endif +/////////////////////////////////////////////////////////////////////////////// +#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_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_firmware_config_flag_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 + 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_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 +/// be above or below the hardware limits - the hardware will clamp +/// appropriately. +typedef struct _ctl_freq_range_t +{ + uint32_t Size; ///< [in] size of this structure + 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 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 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; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Frequency throttle reasons +typedef uint32_t ctl_freq_throttle_reason_flags_t; +typedef enum _ctl_freq_throttle_reason_flag_t +{ + CTL_FREQ_THROTTLE_REASON_FLAG_AVE_PWR_CAP = CTL_BIT(0), ///< frequency throttled due to average power excursion (PL1) + CTL_FREQ_THROTTLE_REASON_FLAG_BURST_PWR_CAP = CTL_BIT(1), ///< frequency throttled due to burst power excursion (PL2) + CTL_FREQ_THROTTLE_REASON_FLAG_CURRENT_LIMIT = CTL_BIT(2), ///< frequency throttled due to current excursion (PL4) + CTL_FREQ_THROTTLE_REASON_FLAG_THERMAL_LIMIT = CTL_BIT(3), ///< frequency throttled due to thermal excursion (T > TjMax) + CTL_FREQ_THROTTLE_REASON_FLAG_PSU_ALERT = CTL_BIT(4), ///< frequency throttled due to power supply assertion + CTL_FREQ_THROTTLE_REASON_FLAG_SW_RANGE = CTL_BIT(5),///< frequency throttled due to software supplied frequency range + CTL_FREQ_THROTTLE_REASON_FLAG_HW_RANGE = CTL_BIT(6),///< frequency throttled due to a sub block that has a lower frequency + ///< range when it receives clocks + CTL_FREQ_THROTTLE_REASON_FLAG_MAX = 0x80000000 + +} ctl_freq_throttle_reason_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Frequency state +typedef struct _ctl_freq_state_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + double currentVoltage; ///< [out] Current voltage in Volts. A negative value indicates that this + ///< property is not known. + double request; ///< [out] The current frequency request in MHz. A negative value indicates + ///< that this property is not known. + double tdp; ///< [out] The maximum frequency in MHz supported under the current TDP + ///< conditions. This fluctuates dynamically based on the power and thermal + ///< limits of the part. A negative value indicates that this property is + ///< not known. + double efficient; ///< [out] The efficient minimum frequency in MHz. A negative value + ///< indicates that this property is not known. + double actual; ///< [out] The resolved frequency in MHz. A negative value indicates that + ///< this property is not known. + ctl_freq_throttle_reason_flags_t throttleReasons; ///< [out] The reasons that the frequency is being limited by the hardware. + ///< Returns 0 (frequency not throttled) or a combination of ::ctl_freq_throttle_reason_flag_t. + +} ctl_freq_state_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Frequency throttle time snapshot +/// +/// @details +/// - Percent time throttled is calculated by taking two snapshots (s1, s2) +/// and using the equation: %throttled = (s2.throttleTime - +/// s1.throttleTime) / (s2.timestamp - s1.timestamp) +typedef struct _ctl_freq_throttle_time_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint64_t throttleTime; ///< [out] The monotonic counter of time in microseconds that the frequency + ///< has been limited by the hardware. + uint64_t timestamp; ///< [out] Microsecond timestamp when throttleTime was captured. + ///< 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_freq_throttle_time_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get handle of frequency domains +/// +/// @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 +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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get frequency properties - available frequencies +/// +/// @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 == hFrequency` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pProperties` +CTL_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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. +/// +/// @returns +/// - CTL_RESULT_SUCCESS +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hFrequency` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pCount` +CTL_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get current frequency limits +/// +/// @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 == hFrequency` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pLimits` +CTL_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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 == hFrequency` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pLimits` +/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS +/// + User does not have permissions to make these modifications. +CTL_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get current frequency state - frequency request, actual frequency, TDP +/// limits +/// +/// @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 == hFrequency` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pState` +CTL_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get frequency throttle time +/// +/// @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 == hFrequency` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pThrottleTime` +CTL_APIEXPORT 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. + ); + + +#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 +#endif +/////////////////////////////////////////////////////////////////////////////// +/// @brief Feature type +typedef enum _ctl_video_processing_feature_t +{ + CTL_VIDEO_PROCESSING_FEATURE_FILM_MODE_DETECTION = 0, ///< Film mode detection. Contains CTL_PROPERTY_VALUE_TYPE_BOOL ValueType. + CTL_VIDEO_PROCESSING_FEATURE_NOISE_REDUCTION = 1, ///< Noise reduction. Contains CTL_PROPERTY_VALUE_TYPE_CUSTOM type field + ///< using struct ::ctl_video_processing_noise_reduction_t. + CTL_VIDEO_PROCESSING_FEATURE_SHARPNESS = 2, ///< Sharpness. Contains CTL_PROPERTY_VALUE_TYPE_UINT32 ValueType. + CTL_VIDEO_PROCESSING_FEATURE_ADAPTIVE_CONTRAST_ENHANCEMENT = 3, ///< Adaptive contrast enhancement. Contains + ///< CTL_PROPERTY_VALUE_TYPE_CUSTOM type field using struct + ///< ::ctl_video_processing_adaptive_contrast_enhancement_t. + CTL_VIDEO_PROCESSING_FEATURE_SUPER_RESOLUTION = 4, ///< Super resolution. Contains CTL_PROPERTY_VALUE_TYPE_CUSTOM ValueType + ///< using ::ctl_video_processing_super_resolution_t. By defaut, Super + ///< resolution is not active, need application to activate it, please + ///< contact Intel for super resolution activation. + CTL_VIDEO_PROCESSING_FEATURE_STANDARD_COLOR_CORRECTION = 5, ///< Standard color correction. Controls Hue, Saturation, Contrast, + ///< Brightness. Contains CTL_PROPERTY_VALUE_TYPE_CUSTOM type field using + ///< struct ::ctl_video_processing_standard_color_correction_t. + CTL_VIDEO_PROCESSING_FEATURE_TOTAL_COLOR_CORRECTION = 6,///< Total color correction. Controls Red, Green, Blue, Yellow, Cyan, + ///< Magenta. Contains CTL_PROPERTY_VALUE_TYPE_CUSTOM type field using + ///< struct ::ctl_video_processing_total_color_correction_t. + CTL_VIDEO_PROCESSING_FEATURE_SKIN_TONE_ENHANCEMENT = 7, ///< Skin tone enhancement. Contains CTL_PROPERTY_VALUE_TYPE_UINT32 + ///< ValueType. + CTL_VIDEO_PROCESSING_FEATURE_MAX + +} ctl_video_processing_feature_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Super resolution values possible +typedef uint32_t ctl_video_processing_super_resolution_flags_t; +typedef enum _ctl_video_processing_super_resolution_flag_t +{ + CTL_VIDEO_PROCESSING_SUPER_RESOLUTION_FLAG_DISABLE = CTL_BIT(0),///< Disable + CTL_VIDEO_PROCESSING_SUPER_RESOLUTION_FLAG_ENABLE_DEFAULT_SCENARIO_MODE = CTL_BIT(1), ///< Enable with default super resolution mode + CTL_VIDEO_PROCESSING_SUPER_RESOLUTION_FLAG_ENABLE_CONFERENCE_SCENARIO_MODE = CTL_BIT(2),///< Super resolution mode targeted at video conference content + CTL_VIDEO_PROCESSING_SUPER_RESOLUTION_FLAG_ENABLE_CAMERA_SCENARIO_MODE = CTL_BIT(3),///< Super resolution mode targeted at camera capture content (e.g. + ///< security camera) + CTL_VIDEO_PROCESSING_SUPER_RESOLUTION_FLAG_MAX = 0x80000000 + +} ctl_video_processing_super_resolution_flag_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Super Resolution feature details structure to be used with +/// SUPER_RESOLUTION +typedef struct _ctl_video_processing_super_resolution_info_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_video_processing_super_resolution_flags_t super_resolution_flag;///< [in,out] SUPER_RESOLUTION flag + ctl_property_info_uint_t super_resolution_range_in_width; ///< [in,out] The range of input width information(min, max, default and + ///< step size)which super resolution is capable of supporting. + ctl_property_info_uint_t super_resolution_range_in_height; ///< [in,out] The range of input height information(min, max, default and + ///< step size)which super resolution is capable of supporting. + uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes + +} ctl_video_processing_super_resolution_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Super Resolution Get/Set structure to be used with SUPER_RESOLUTION +typedef struct _ctl_video_processing_super_resolution_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_video_processing_super_resolution_flags_t super_resolution_flag;///< [in,out] SUPER_RESOLUTION flag + bool super_resolution_max_in_enabled; ///< [in,out] The enabling of maximum input width and height limition. If + ///< enabled, super resolution will always take effect if the input + ///< resolution is smaller than the below specified max resolution; + ///< otherwise, super_resolution_max_in_width and + ///< super_resolution_max_in_height will be ignored + uint32_t super_resolution_max_in_width; ///< [in,out] The maximum input width limition value setting which super + ///< resolution will be allowed to enabled. + uint32_t super_resolution_max_in_height; ///< [in,out] The maximum input height limiation value setting which super + ///< resolution will be allowed to enabled. + bool super_resolution_reboot_reset; ///< [in,out] Resetting of super resolution after rebooting. + uint32_t ReservedFields[15]; ///< [out] Reserved field of 60 bytes + char ReservedBytes[3]; ///< [out] Reserved field of 3 bytes + +} ctl_video_processing_super_resolution_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Noise Reduction feature details structure to be used with +/// NOISE_REDUCTION +typedef struct _ctl_video_processing_noise_reduction_info_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_property_info_uint_t noise_reduction; ///< [in,out] Noise reduction min, max, default and step size information + bool noise_reduction_auto_detect_supported; ///< [in,out] Noise reduction Auto Detect is supported; only valid if + ///< NOISE_REDUCTION is enabled. If enabled, noise reduction level is + ///< automatically determined and set value is not used. + ctl_property_info_boolean_t noise_reduction_auto_detect;///< [in,out] Noise reduction auto detect default information + uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes + +} ctl_video_processing_noise_reduction_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Noise Reduction Get/Set structure to be used with NOISE_REDUCTION +typedef struct _ctl_video_processing_noise_reduction_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_property_uint_t noise_reduction; ///< [in,out] Noise reduction enable and value setting + ctl_property_boolean_t noise_reduction_auto_detect; ///< [in,out] Noise reduction auto detect setting + uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes + +} ctl_video_processing_noise_reduction_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Adaptive Contrast Enhancement feature details structure to be used +/// with ADAPTIVE_CONTRAST_ENHANCEMENT +typedef struct _ctl_video_processing_adaptive_contrast_enhancement_info_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_property_info_uint_t adaptive_contrast_enhancement; ///< [in,out] Adaptive Contrast Enhancement min, max, default and step size + ///< information + bool adaptive_contrast_enhancement_coexistence_supported; ///< [in,out] Adaptive contrast enhancement coexistance is supported; only + ///< valid if ADAPTIVE_CONTRAST_ENHANCEMENT is enabled. If enabled, Video + ///< adaptive contrast ehancement will be allowed to be enabled and coexist + ///< with Display adaptive contrast ehancement feature. + ctl_property_info_boolean_t adaptive_contrast_enhancement_coexistence; ///< [in,out] Adaptive contrast enhancement coexistence default information + uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes + +} ctl_video_processing_adaptive_contrast_enhancement_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Adaptive Contrast Enhancement Get/Set structure to be used with +/// ADAPTIVE_CONTRAST_ENHANCEMENT +typedef struct _ctl_video_processing_adaptive_contrast_enhancement_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_property_uint_t adaptive_contrast_enhancement; ///< [in,out] Adaptive Contrast Enhancement enable and value setting + ctl_property_boolean_t adaptive_contrast_enhancement_coexistence; ///< [in,out] Adaptive contrast enhancement coexistance setting + uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes + +} ctl_video_processing_adaptive_contrast_enhancement_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Standard Color Correction feature details structure to be used with +/// STANDARD_COLOR_CORRECTION +typedef struct _ctl_video_processing_standard_color_correction_info_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + bool standard_color_correction_default_enable; ///< [in,out] STANDARD_COLOR_CORRECTION default enable setting. This + ///< global settings controls all of Hue, Saturation, Contrast, Brightness + ///< enabling. Individual Enable controls shall be ignored. + ctl_property_info_float_t brightness; ///< [in,out] Brightness min, max, default and step size information + ctl_property_info_float_t contrast; ///< [in,out] Contrast min, max, default and step size information + ctl_property_info_float_t hue; ///< [in,out] Hue min, max, default and step size information + ctl_property_info_float_t saturation; ///< [in,out] Saturation min, max, default and step size information + uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes + +} ctl_video_processing_standard_color_correction_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Standard Color Correction Get/Set structure to be used with +/// STANDARD_COLOR_CORRECTION +typedef struct _ctl_video_processing_standard_color_correction_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + bool standard_color_correction_enable; ///< [in,out] STANDARD_COLOR_CORRECTION enable setting. This global + ///< setting controls all of Hue, Saturation, Contrast, Brightness + ///< enabling. + float brightness; ///< [in,out] Brightness value + float contrast; ///< [in,out] Contrast value + float hue; ///< [in,out] Hue value + float saturation; ///< [in,out] Saturation value + uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes + +} ctl_video_processing_standard_color_correction_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Total Color Correction Get/Set structure to be used with +/// TOTAL_COLOR_CORRECTION +typedef struct _ctl_video_processing_total_color_correction_info_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + bool total_color_correction_default_enable; ///< [in,out] TOTAL_COLOR_CORRECTION enable setting. This global setting + ///< controls all of Red, Green, Blue, Yellow, Cyan, Magenta enabling. + ///< Individual Enable controls shall be ignored. + ctl_property_info_uint_t red; ///< [in,out] Red min, max, default and step size information + ctl_property_info_uint_t green; ///< [in,out] Green min, max, default and step size information + ctl_property_info_uint_t blue; ///< [in,out] Blue min, max, default and step size information + ctl_property_info_uint_t yellow; ///< [in,out] Yellow min, max, default and step size information + ctl_property_info_uint_t cyan; ///< [in,out] Cyan min, max, default and step size information + ctl_property_info_uint_t magenta; ///< [in,out] Magenta min, max, default and step size information + uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes + +} ctl_video_processing_total_color_correction_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Total Color Correction Get/Set structure to be used with +/// TOTAL_COLOR_CORRECTION +typedef struct _ctl_video_processing_total_color_correction_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + bool total_color_correction_enable; ///< [in,out] TOTAL_COLOR_CORRECTION enable setting. This global setting + ///< controls all of Red, Green, Blue, Yellow, Cyan, Magenta enabling. + uint32_t red; ///< [in,out] Red value + uint32_t green; ///< [in,out] Green value + uint32_t blue; ///< [in,out] Blue value + uint32_t yellow; ///< [in,out] Yellow value + uint32_t cyan; ///< [in,out] Cyan value + uint32_t magenta; ///< [in,out] Magenta value + uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes + +} ctl_video_processing_total_color_correction_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Video Processing feature details which will have range supported and +/// default values +typedef struct _ctl_video_processing_feature_details_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_video_processing_feature_t FeatureType; ///< [out] Video processing feature type + ctl_property_value_type_t ValueType; ///< [out] Type of value + ctl_property_info_t Value; ///< [out] Union of various type of values for Video Processing features. + ///< For enum types this can be noise reduction, color control etc. This + ///< member is valid iff ValueType is not CTL_PROPERTY_VALUE_TYPE_CUSTOM + int32_t CustomValueSize; ///< [in] CustomValue buffer size + void* pCustomValue; ///< [in,out] Pointer to a custom structure. Features that use CustomType, + ///< after the first query for all of the supported features the user needs + ///< to allocate this buffer and then query again just this specific + ///< feature for the structure to be filled in. Caller should allocate this + ///< buffer with known custom feature structure size. This member is valid + ///< iff ValueType is CTL_PROPERTY_VALUE_TYPE_CUSTOM. + uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes + +} ctl_video_processing_feature_details_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Video Processing features which are controllable +typedef struct _ctl_video_processing_feature_caps_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint32_t NumSupportedFeatures; ///< [in,out] Number of elements in supported features array + ctl_video_processing_feature_details_t* pFeatureDetails;///< [in,out] Array of supported features and their details + uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes + +} ctl_video_processing_feature_caps_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Video Processing feature for get/set +typedef struct _ctl_video_processing_feature_getset_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_video_processing_feature_t FeatureType; ///< [in] Features interested in + char* ApplicationName; ///< [in] Application name for which the property type is applicable. If + ///< this is an empty string then this will get/set global settings for the + ///< given adapter. Note that this should contain only the name of the + ///< application and not the system specific path. [This is not currently + ///< supported and should be an empty string.] + int8_t ApplicationNameLength; ///< [in] Length of ApplicationName string + bool bSet; ///< [in] Set this if it's a set call + ctl_property_value_type_t ValueType; ///< [in] Type of value. Caller has to ensure it provides the right value + ///< type which decides how one read the union structure below + ctl_property_t Value; ///< [in,out] Union of various type of values for Video Processing + ///< features. For enum types this can be noise reduction, color control + ///< etc. This member is valid iff ValueType is not + ///< CTL_PROPERTY_VALUE_TYPE_CUSTOM + int32_t CustomValueSize; ///< [in] CustomValue buffer size. For a feature requiring custom struct, + ///< caller will know of it upfront the struct to use based on the feautre + ///< and can provide the right size info here + void* pCustomValue; ///< [in,out] Pointer to a custom structure. Caller should allocate this + ///< buffer with known custom feature structure size. This member is valid + ///< iff ValueType is CTL_PROPERTY_VALUE_TYPE_CUSTOM + uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes + +} ctl_video_processing_feature_getset_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @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_APIEXPORT 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 + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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_APIEXPORT 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 + ); + + +#if !defined(__GNUC__) +#pragma endregion // media +#endif +// Intel 'ctlApi' for Device Adapter - Memory management +#if !defined(__GNUC__) +#pragma region memory +#endif +/////////////////////////////////////////////////////////////////////////////// +/// @brief Memory module types +typedef enum _ctl_mem_type_t +{ + CTL_MEM_TYPE_HBM = 0, ///< HBM memory + CTL_MEM_TYPE_DDR = 1, ///< DDR memory + CTL_MEM_TYPE_DDR3 = 2, ///< DDR3 memory + CTL_MEM_TYPE_DDR4 = 3, ///< DDR4 memory + CTL_MEM_TYPE_DDR5 = 4, ///< DDR5 memory + CTL_MEM_TYPE_LPDDR = 5, ///< LPDDR memory + CTL_MEM_TYPE_LPDDR3 = 6, ///< LPDDR3 memory + CTL_MEM_TYPE_LPDDR4 = 7, ///< LPDDR4 memory + CTL_MEM_TYPE_LPDDR5 = 8, ///< LPDDR5 memory + CTL_MEM_TYPE_GDDR4 = 9, ///< GDDR4 memory + CTL_MEM_TYPE_GDDR5 = 10, ///< GDDR5 memory + CTL_MEM_TYPE_GDDR5X = 11, ///< GDDR5X memory + CTL_MEM_TYPE_GDDR6 = 12, ///< GDDR6 memory + CTL_MEM_TYPE_GDDR6X = 13, ///< GDDR6X memory + CTL_MEM_TYPE_GDDR7 = 14, ///< GDDR7 memory + CTL_MEM_TYPE_UNKNOWN = 15, ///< UNKNOWN memory + CTL_MEM_TYPE_MAX + +} ctl_mem_type_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Memory module location +typedef enum _ctl_mem_loc_t +{ + CTL_MEM_LOC_SYSTEM = 0, ///< System memory + CTL_MEM_LOC_DEVICE = 1, ///< On board local device memory + CTL_MEM_LOC_MAX + +} ctl_mem_loc_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Memory properties +typedef struct _ctl_mem_properties_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_mem_type_t type; ///< [out] The memory type + ctl_mem_loc_t location; ///< [out] Location of this memory (system, device) + uint64_t physicalSize; ///< [out] Physical memory size in bytes. A value of 0 indicates that this + ///< property is not known. However, a call to ::ctlMemoryGetState() will + ///< correctly return the total size of usable memory. + int32_t busWidth; ///< [out] Width of the memory bus. A value of -1 means that this property + ///< is unknown. + int32_t numChannels; ///< [out] The number of memory channels. A value of -1 means that this + ///< property is unknown. + +} ctl_mem_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Memory state - health, allocated +/// +/// @details +/// - Percent allocation is given by 100 * (size - free / size. +/// - Percent free is given by 100 * free / size. +typedef struct _ctl_mem_state_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint64_t free; ///< [out] The free memory in bytes + uint64_t size; ///< [out] The total allocatable memory in bytes (can be less than + ///< ::ctl_mem_properties_t.physicalSize) + +} ctl_mem_state_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Memory bandwidth +/// +/// @details +/// - Percent bandwidth is calculated by taking two snapshots (s1, s2) and +/// using the equation: %bw = 10^6 * ((s2.readCounter - s1.readCounter) + +/// (s2.writeCounter - s1.writeCounter)) / (s2.maxBandwidth * +/// (s2.timestamp - s1.timestamp)) +typedef struct _ctl_mem_bandwidth_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint64_t maxBandwidth; ///< [out] Current maximum bandwidth in units of bytes/sec + uint64_t timestamp; ///< [out] The timestamp (in microseconds) when these measurements were 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. + uint64_t readCounter; ///< [out] Total bytes read from memory. Supported only for Version > 0 + uint64_t writeCounter; ///< [out] Total bytes written to memory. Supported only for Version > 0 + +} ctl_mem_bandwidth_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @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_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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_APIEXPORT 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. + ); + + +#if !defined(__GNUC__) +#pragma endregion // memory +#endif +// Intel 'ctlApi' for Device Adapter - Overclock +#if !defined(__GNUC__) +#pragma region overclock +#endif +/////////////////////////////////////////////////////////////////////////////// +/// @brief Telemetry Item for each telemetry property +/// +/// @details +/// - If the supported field is true, then the entire structure has valid +/// information. +/// - The ::ctl_data_value_t is of type ::ctl_data_type_t and units +/// ::ctl_units_t +typedef struct _ctl_oc_telemetry_item_t +{ + bool bSupported; ///< [out] Indicates if the value is supported. + ctl_units_t units; ///< [out] Indicates the units of the value. + ctl_data_type_t type; ///< [out] Indicates the data type. + ctl_data_value_t value; ///< [out] The value of type ::ctl_data_type_t and units ::ctl_units_t. + +} ctl_oc_telemetry_item_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Overclocking Control Information +/// +/// @details +/// - Whether the device supports overclocking. +/// - The +/// bSupported/bRelative/bReference/units/min/max/step/default/reference +/// values for the available overclock controls +/// - The idea is to facilitate the way the applications present overclock +/// settings to the user. If bSupported is false, the corresponding +/// overclock control is not supported +/// - The setting units will be an enum that enables the application to know +/// the units for the control setting e.g. MHz. The min and max settings +/// give the limits for the control. +/// - The step setting gives the minimum change in the control value (plus +/// or minus) - if a control is not changed by at least this amount, the +/// hardware may round up or down. +/// - The default values gives the manufacturing setting for the control. +/// Some controls such as frequency offset and voltage offset are +/// relative; in this case, bRelative will be true, otherwise the control +/// settings are absolute values. +/// - For relative controls and if bReference is true, the reference value +/// gives the absolute value at the default setting. +/// - If bReference is false, the absolute value of the default setting is +/// no not known and it is probably better to display the setting to users +/// as percentage offsets. +typedef struct _ctl_oc_control_info_t +{ + bool bSupported; ///< [out] Indicates if the values are known. + bool bRelative; ///< [out] Indicates if the values are meant to be taken as relative values + ///< instead of absolut values. + bool bReference; ///< [out] For relative values, this indicates if a reference is available. + ctl_units_t units; ///< [out] Units for the values. + double min; ///< [out] Minimum Value. + double max; ///< [out] Maximum Value. + double step; ///< [out] Step Value. + double Default; ///< [out] Default Value. + double reference; ///< [out] Reference Value if the bReference is true. + +} ctl_oc_control_info_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Overclock properties +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 ::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 ::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; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Overclock Voltage Frequency Pair +typedef struct _ctl_oc_vf_pair_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + double Voltage; ///< [in,out] Voltage component of the pair in mV. + double Frequency; ///< [in,out] Frequency component of the pair in MHz. + +} ctl_oc_vf_pair_t; + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_PSU_COUNT +/// @brief Maximum number power supply units. +#define CTL_PSU_COUNT 5 +#endif // CTL_PSU_COUNT + +/////////////////////////////////////////////////////////////////////////////// +/// @brief PSU Type. +typedef enum _ctl_psu_type_t +{ + CTL_PSU_TYPE_PSU_NONE = 0, ///< Type of the PSU is unknown. + CTL_PSU_TYPE_PSU_PCIE = 1, ///< Type of the PSU is PCIe + CTL_PSU_TYPE_PSU_6PIN = 2, ///< Type of the PSU is 6 PIN + CTL_PSU_TYPE_PSU_8PIN = 3, ///< Type of the PSU is 8 PIN + CTL_PSU_TYPE_MAX + +} ctl_psu_type_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief PSU Info +typedef struct _ctl_psu_info_t +{ + bool bSupported; ///< [out] Indicates if this PSU entry is supported. + ctl_psu_type_t psuType; ///< [out] Type of the PSU. + ctl_oc_telemetry_item_t energyCounter; ///< [out] Snapshot of the monotonic energy counter maintained by hardware. + ///< It measures the total energy consumed this power source. By taking the + ///< delta between two snapshots and dividing by the delta time in seconds, + ///< an application can compute the average power. + ctl_oc_telemetry_item_t voltage; ///< [out] Instantaneous snapshot of the voltage of this power source. + +} ctl_psu_info_t; + +/////////////////////////////////////////////////////////////////////////////// +#ifndef CTL_FAN_COUNT +/// @brief Maximum number of Fans +#define CTL_FAN_COUNT 5 +#endif // CTL_FAN_COUNT + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Power Telemetry +typedef struct _ctl_power_telemetry_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_oc_telemetry_item_t timeStamp; ///< [out] Snapshot of the timestamp counter that measures the total time + ///< since Jan 1, 1970 UTC. It is a decimal value in seconds with a minimum + ///< accuracy of 1 millisecond. + ctl_oc_telemetry_item_t gpuEnergyCounter; ///< [out] Snapshot of the monotonic energy counter maintained by hardware. + ///< It measures the total energy consumed by the GPU chip. By taking the + ///< delta between two snapshots and dividing by the delta time in seconds, + ///< an application can compute the average power. + ctl_oc_telemetry_item_t gpuVoltage; ///< [out] Instantaneous snapshot of the voltage feeding the GPU chip. It + ///< is measured at the power supply output - chip input will be lower. + ctl_oc_telemetry_item_t gpuCurrentClockFrequency; ///< [out] Instantaneous snapshot of the GPU chip frequency. + ctl_oc_telemetry_item_t gpuCurrentTemperature; ///< [out] Instantaneous snapshot of the GPU chip temperature, read from + ///< the sensor reporting the highest value. + ctl_oc_telemetry_item_t globalActivityCounter; ///< [out] Snapshot of the monotonic global activity counter. It measures + ///< the time in seconds (accurate down to 1 millisecond) that any GPU + ///< engine is busy. By taking the delta between two snapshots and dividing + ///< by the delta time in seconds, an application can compute the average + ///< percentage utilization of the GPU.. + ctl_oc_telemetry_item_t renderComputeActivityCounter; ///< [out] Snapshot of the monotonic 3D/compute activity counter. It + ///< measures the time in seconds (accurate down to 1 millisecond) that any + ///< 3D render/compute engine is busy. By taking the delta between two + ///< snapshots and dividing by the delta time in seconds, an application + ///< can compute the average percentage utilization of all 3D + ///< render/compute blocks in the GPU. + ctl_oc_telemetry_item_t mediaActivityCounter; ///< [out] Snapshot of the monotonic media activity counter. It measures + ///< the time in seconds (accurate down to 1 millisecond) that any media + ///< engine is busy. By taking the delta between two snapshots and dividing + ///< by the delta time in seconds, an application can compute the average + ///< 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 ::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 + ///< ::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 ::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. + ///< It measures the total energy consumed by the local memory modules. By + ///< taking the delta between two snapshots and dividing by the delta time + ///< in seconds, an application can compute the average power. + ctl_oc_telemetry_item_t vramVoltage; ///< [out] Instantaneous snapshot of the voltage feeding the memory + ///< modules. + ctl_oc_telemetry_item_t vramCurrentClockFrequency; ///< [out] Instantaneous snapshot of the raw clock frequency driving the + ///< memory modules. + ctl_oc_telemetry_item_t vramCurrentEffectiveFrequency; ///< [out] Instantaneous snapshot of the effective data transfer rate that + ///< the memory modules can sustain based on the current clock frequency.. + ctl_oc_telemetry_item_t vramReadBandwidthCounter; ///< [out] Instantaneous snapshot of the monotonic counter that measures + ///< the read traffic from the memory modules. By taking the delta between + ///< two snapshots and dividing by the delta time in seconds, an + ///< application can compute the average read bandwidth. + ctl_oc_telemetry_item_t vramWriteBandwidthCounter; ///< [out] Instantaneous snapshot of the monotonic counter that measures + ///< 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 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; + +/////////////////////////////////////////////////////////////////////////////// +/// @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_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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_APIEXPORT ctl_result_t CTL_APICALL +ctlOverclockWaiverSet( + ctl_device_adapter_handle_t hDeviceHandle ///< [in][release] Handle to display adapter + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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_APIEXPORT 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. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @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 ocMaxVoltageOffset ///< [in] The Overclocking Maximum Voltage Desired in units given in + ///< ::ctl_oc_properties_t::gpuVoltageOffset::units returned from + ///< ::ctlOverclockGetProperties() + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get the current Overclock Vram Memory Speed +/// +/// @details +/// - 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 +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceHandle` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pOcVramMemSpeedLimit` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlOverclockVramMemSpeedLimitGetV2( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + 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 desired Overclock Vram Memory Speed +/// +/// @details +/// - 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 +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceHandle` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlOverclockVramMemSpeedLimitSetV2( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double ocVramMemSpeedLimit ///< [in] The desired Memory Speed in units given in + ///< ::ctl_oc_properties_t::vramMemSpeedLimit::units returned from + ///< ::ctlOverclockGetProperties() + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get the Current Sustained power limit +/// +/// @details +/// - The purpose of this function is to read the current sustained power +/// limit. +/// - 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 +/// - 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 +ctlOverclockPowerLimitGetV2( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + 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 +/// +/// @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 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 +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceHandle` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlOverclockPowerLimitSetV2( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + 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 +/// +/// @details +/// - 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 +/// - 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 +ctlOverclockTemperatureLimitGetV2( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + 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 +/// +/// @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 +/// - CTL_RESULT_ERROR_UNINITIALIZED +/// - CTL_RESULT_ERROR_DEVICE_LOST +/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE +/// + `nullptr == hDeviceHandle` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlOverclockTemperatureLimitSetV2( + ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter + double temperatureLimit ///< [in] The desired temperature limit in Units given in + ///< ::ctl_oc_properties_t::temperatureLimit::units returned from + ///< ::ctlOverclockGetProperties() + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Read VF Curve +/// +/// @details +/// - 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 == 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 +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 Write Custom VF curve +/// +/// @details +/// - 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 == hDeviceAdapter` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pCustomVFCurveTable` +/// - CTL_RESULT_ERROR_UNKNOWN - "Unknown Error" +CTL_APIEXPORT ctl_result_t CTL_APICALL +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 + ); + + +#if !defined(__GNUC__) +#pragma endregion // overclock +#endif +// Intel 'ctlApi' for Device Adapter - PCI Information +#if !defined(__GNUC__) +#pragma region pci +#endif +/////////////////////////////////////////////////////////////////////////////// +/// @brief PCI address +typedef struct _ctl_pci_address_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint32_t domain; ///< [out] BDF domain + uint32_t bus; ///< [out] BDF bus + uint32_t device; ///< [out] BDF device + uint32_t function; ///< [out] BDF function + +} ctl_pci_address_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief PCI speed +typedef struct _ctl_pci_speed_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + int32_t gen; ///< [out] The link generation. A value of -1 means that this property is + ///< unknown. + int32_t width; ///< [out] The number of lanes. A value of -1 means that this property is + ///< unknown. + int64_t maxBandwidth; ///< [out] The maximum bandwidth in bytes/sec (sum of all lanes). A value + ///< of -1 means that this property is unknown. + +} ctl_pci_speed_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Static PCI properties +typedef struct _ctl_pci_properties_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_pci_address_t address; ///< [out] The BDF address + ctl_pci_speed_t maxSpeed; ///< [out] Fastest port configuration supported by the device (sum of all + ///< lanes) + bool resizable_bar_supported; ///< [out] Support for Resizable Bar on this device. + bool resizable_bar_enabled; ///< [out] Resizable Bar enabled on this device + +} ctl_pci_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Dynamic PCI state +typedef struct _ctl_pci_state_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_pci_speed_t speed; ///< [out] The current port configure speed + +} ctl_pci_state_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get PCI properties - address, max speed +/// +/// @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 +ctlPciGetProperties( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + ctl_pci_properties_t* pProperties ///< [in,out] Will contain the PCI properties. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get current PCI state - current speed +/// +/// @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_APIEXPORT ctl_result_t CTL_APICALL +ctlPciGetState( + ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter + ctl_pci_state_t* pState ///< [in,out] Will contain the PCI properties. + ); + + +#if !defined(__GNUC__) +#pragma endregion // pci +#endif +// Intel 'ctlApi' for Device Adapter - Power management +#if !defined(__GNUC__) +#pragma region power +#endif +/////////////////////////////////////////////////////////////////////////////// +/// @brief Properties related to device power settings +typedef struct _ctl_power_properties_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + bool canControl; ///< [out] Software can change the power limits of this domain assuming the + ///< user has permissions. + int32_t defaultLimit; ///< [out] The factory default TDP power limit of the part in milliwatts. A + ///< value of -1 means that this is not known. + int32_t minLimit; ///< [out] The minimum power limit in milliwatts that can be requested. + int32_t maxLimit; ///< [out] The maximum power limit in milliwatts that can be requested. + +} ctl_power_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Energy counter snapshot +/// +/// @details +/// - Average power is calculated by taking two snapshots (s1, s2) and using +/// the equation: PowerWatts = (s2.energy - s1.energy) / (s2.timestamp - +/// s1.timestamp) +typedef struct _ctl_power_energy_counter_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + uint64_t energy; ///< [out] The monotonic energy counter in microjoules. + uint64_t timestamp; ///< [out] Microsecond timestamp when energy was captured. + ///< 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_power_energy_counter_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Sustained power limits +/// +/// @details +/// - The power controller (Punit) will throttle the operating frequency if +/// the power averaged over a window (typically seconds) exceeds this +/// limit. +typedef struct _ctl_power_sustained_limit_t +{ + bool enabled; ///< [in,out] indicates if the limit is enabled (true) or ignored (false) + int32_t power; ///< [in,out] power limit in milliwatts + int32_t interval; ///< [in,out] power averaging window (Tau) in milliseconds + +} ctl_power_sustained_limit_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Burst power limit +/// +/// @details +/// - The power controller (Punit) will throttle the operating frequency of +/// the device if the power averaged over a few milliseconds exceeds a +/// limit known as PL2. Typically PL2 > PL1 so that it permits the +/// frequency to burst higher for short periods than would be otherwise +/// permitted by PL1. +typedef struct _ctl_power_burst_limit_t +{ + bool enabled; ///< [in,out] indicates if the limit is enabled (true) or ignored (false) + int32_t power; ///< [in,out] power limit in milliwatts + +} ctl_power_burst_limit_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Peak power limit +/// +/// @details +/// - The power controller (Punit) will preemptively throttle the operating +/// frequency of the device when the instantaneous power exceeds this +/// limit. The limit is known as PL4. It expresses the maximum power that +/// can be drawn from the power supply. +/// - If this power limit is removed or set too high, the power supply will +/// generate an interrupt when it detects an overcurrent condition and the +/// power controller will throttle the device frequencies down to min. It +/// is thus better to tune the PL4 value in order to avoid such +/// excursions. +typedef struct _ctl_power_peak_limit_t +{ + int32_t powerAC; ///< [in,out] power limit in milliwatts for the AC power source. + int32_t powerDC; ///< [in,out] power limit in milliwatts for the DC power source. On input, + ///< this is ignored if the product does not have a battery. On output, + ///< this will be -1 if the product does not have a battery. + +} ctl_power_peak_limit_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Power limits +typedef struct _ctl_power_limits_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_power_sustained_limit_t sustainedPowerLimit;///< [in,out] sustained power limit. + ctl_power_burst_limit_t burstPowerLimit; ///< [in,out] burst power limit. + ctl_power_peak_limit_t peakPowerLimits; ///< [in,out] peak power limit. + +} ctl_power_limits_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Energy threshold +/// +/// @details +/// - . +typedef struct _ctl_energy_threshold_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + bool enable; ///< [in,out] Indicates if the energy threshold is enabled. + double threshold; ///< [in,out] The energy threshold in Joules. Will be 0.0 if no threshold + ///< has been set. + uint32_t processId; ///< [in,out] The host process ID that set the energy threshold. Will be + ///< 0xFFFFFFFF if no threshold has been set. + +} ctl_energy_threshold_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get handle of power domains +/// +/// @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 +ctlEnumPowerDomains( + 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_pwr_handle_t* phPower ///< [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 properties related to a power domain +/// +/// @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 == hPower` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pProperties` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlPowerGetProperties( + ctl_pwr_handle_t hPower, ///< [in] Handle for the component. + ctl_power_properties_t* pProperties ///< [in,out] Structure that will contain property data. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get energy counter +/// +/// @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 == hPower` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pEnergy` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlPowerGetEnergyCounter( + ctl_pwr_handle_t hPower, ///< [in] Handle for the component. + ctl_power_energy_counter_t* pEnergy ///< [in,out] Will contain the latest snapshot of the energy counter and + ///< timestamp when the last counter value was measured. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get power limits +/// +/// @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 == hPower` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlPowerGetLimits( + ctl_pwr_handle_t hPower, ///< [in] Handle for the component. + ctl_power_limits_t* pPowerLimits ///< [in,out][optional] Structure that will contain the power limits. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Set power limits +/// +/// @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 == hPower` +/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS +/// + User does not have permissions to make these modifications. +/// - ::CTL_RESULT_ERROR_NOT_AVAILABLE +/// + The device is in use, meaning that the GPU is under Over clocking, applying power limits under overclocking is not supported. +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlPowerSetLimits( + ctl_pwr_handle_t hPower, ///< [in] Handle for the component. + const ctl_power_limits_t* pPowerLimits ///< [in][optional] Structure that will contain the power limits. + ); + + +#if !defined(__GNUC__) +#pragma endregion // power +#endif +// Intel 'ctlApi' for Device Adapter - Temperature Sensors +#if !defined(__GNUC__) +#pragma region temperature +#endif +/////////////////////////////////////////////////////////////////////////////// +/// @brief Temperature sensors +typedef enum _ctl_temp_sensors_t +{ + CTL_TEMP_SENSORS_GLOBAL = 0, ///< The maximum temperature across all device sensors + CTL_TEMP_SENSORS_GPU = 1, ///< The maximum temperature across all sensors in the GPU + CTL_TEMP_SENSORS_MEMORY = 2, ///< The maximum temperature across all sensors in the local memory + CTL_TEMP_SENSORS_GLOBAL_MIN = 3, ///< The minimum temperature across all device sensors + CTL_TEMP_SENSORS_GPU_MIN = 4, ///< The minimum temperature across all sensors in the GPU + CTL_TEMP_SENSORS_MEMORY_MIN = 5, ///< The minimum temperature across all sensors in the local device memory + CTL_TEMP_SENSORS_MAX + +} ctl_temp_sensors_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Temperature sensor properties +typedef struct _ctl_temp_properties_t +{ + uint32_t Size; ///< [in] size of this structure + uint8_t Version; ///< [in] version of this structure + ctl_temp_sensors_t type; ///< [out] Which part of the device the temperature sensor measures + double maxTemperature; ///< [out] Will contain the maximum temperature for the specific device in + ///< degrees Celsius. + +} ctl_temp_properties_t; + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get handle of temperature sensors +/// +/// @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 +ctlEnumTemperatureSensors( + 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_temp_handle_t* phTemperature ///< [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 temperature sensor 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 == hTemperature` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pProperties` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlTemperatureGetProperties( + ctl_temp_handle_t hTemperature, ///< [in] Handle for the component. + ctl_temp_properties_t* pProperties ///< [in,out] Will contain the temperature sensor properties. + ); + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Get the temperature from a specified sensor +/// +/// @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 == hTemperature` +/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER +/// + `nullptr == pTemperature` +CTL_APIEXPORT ctl_result_t CTL_APICALL +ctlTemperatureGetState( + ctl_temp_handle_t hTemperature, ///< [in] Handle for the component. + double* pTemperature ///< [in,out] Will contain the temperature read from the specified sensor + ///< in degrees Celsius. + ); + + +#if !defined(__GNUC__) +#pragma endregion // temperature +#endif + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlInit +typedef ctl_result_t (CTL_APICALL *ctl_pfnInit_t)( + ctl_init_args_t*, + ctl_api_handle_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlClose +typedef ctl_result_t (CTL_APICALL *ctl_pfnClose_t)( + ctl_api_handle_t + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlSetRuntimePath +typedef ctl_result_t (CTL_APICALL *ctl_pfnSetRuntimePath_t)( + ctl_runtime_path_args_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlWaitForPropertyChange +typedef ctl_result_t (CTL_APICALL *ctl_pfnWaitForPropertyChange_t)( + ctl_device_adapter_handle_t, + ctl_wait_property_change_args_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlReservedCall +typedef ctl_result_t (CTL_APICALL *ctl_pfnReservedCall_t)( + ctl_device_adapter_handle_t, + ctl_reserved_args_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetSupported3DCapabilities +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSupported3DCapabilities_t)( + ctl_device_adapter_handle_t, + ctl_3d_feature_caps_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetSet3DFeature +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSet3DFeature_t)( + ctl_device_adapter_handle_t, + ctl_3d_feature_getset_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlCheckDriverVersion +typedef ctl_result_t (CTL_APICALL *ctl_pfnCheckDriverVersion_t)( + ctl_device_adapter_handle_t, + ctl_version_info_t + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlEnumerateDevices +typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumerateDevices_t)( + ctl_api_handle_t, + uint32_t*, + ctl_device_adapter_handle_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlEnumerateDisplayOutputs +typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumerateDisplayOutputs_t)( + ctl_device_adapter_handle_t, + uint32_t*, + ctl_display_output_handle_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlEnumerateI2CPinPairs +typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumerateI2CPinPairs_t)( + ctl_device_adapter_handle_t, + uint32_t*, + ctl_i2c_pin_pair_handle_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetDeviceProperties +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetDeviceProperties_t)( + ctl_device_adapter_handle_t, + ctl_device_adapter_properties_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetDisplayProperties +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetDisplayProperties_t)( + ctl_display_output_handle_t, + ctl_display_properties_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetAdaperDisplayEncoderProperties +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetAdaperDisplayEncoderProperties_t)( + ctl_display_output_handle_t, + ctl_adapter_display_encoder_properties_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetZeDevice +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetZeDevice_t)( + ctl_device_adapter_handle_t, + void*, + void** + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetSharpnessCaps +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSharpnessCaps_t)( + ctl_display_output_handle_t, + ctl_sharpness_caps_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetCurrentSharpness +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetCurrentSharpness_t)( + ctl_display_output_handle_t, + ctl_sharpness_settings_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlSetCurrentSharpness +typedef ctl_result_t (CTL_APICALL *ctl_pfnSetCurrentSharpness_t)( + ctl_display_output_handle_t, + ctl_sharpness_settings_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlI2CAccess +typedef ctl_result_t (CTL_APICALL *ctl_pfnI2CAccess_t)( + ctl_display_output_handle_t, + ctl_i2c_access_args_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlI2CAccessOnPinPair +typedef ctl_result_t (CTL_APICALL *ctl_pfnI2CAccessOnPinPair_t)( + ctl_i2c_pin_pair_handle_t, + ctl_i2c_access_pinpair_args_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlAUXAccess +typedef ctl_result_t (CTL_APICALL *ctl_pfnAUXAccess_t)( + ctl_display_output_handle_t, + ctl_aux_access_args_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetPowerOptimizationCaps +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetPowerOptimizationCaps_t)( + ctl_display_output_handle_t, + ctl_power_optimization_caps_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetPowerOptimizationSetting +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetPowerOptimizationSetting_t)( + ctl_display_output_handle_t, + ctl_power_optimization_settings_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlSetPowerOptimizationSetting +typedef ctl_result_t (CTL_APICALL *ctl_pfnSetPowerOptimizationSetting_t)( + ctl_display_output_handle_t, + ctl_power_optimization_settings_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlSetBrightnessSetting +typedef ctl_result_t (CTL_APICALL *ctl_pfnSetBrightnessSetting_t)( + ctl_display_output_handle_t, + ctl_set_brightness_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetBrightnessSetting +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetBrightnessSetting_t)( + ctl_display_output_handle_t, + ctl_get_brightness_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlPixelTransformationGetConfig +typedef ctl_result_t (CTL_APICALL *ctl_pfnPixelTransformationGetConfig_t)( + ctl_display_output_handle_t, + ctl_pixtx_pipe_get_config_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlPixelTransformationSetConfig +typedef ctl_result_t (CTL_APICALL *ctl_pfnPixelTransformationSetConfig_t)( + ctl_display_output_handle_t, + ctl_pixtx_pipe_set_config_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlPanelDescriptorAccess +typedef ctl_result_t (CTL_APICALL *ctl_pfnPanelDescriptorAccess_t)( + ctl_display_output_handle_t, + ctl_panel_descriptor_access_args_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetSupportedRetroScalingCapability +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSupportedRetroScalingCapability_t)( + ctl_device_adapter_handle_t, + ctl_retro_scaling_caps_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetSetRetroScaling +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSetRetroScaling_t)( + ctl_device_adapter_handle_t, + ctl_retro_scaling_settings_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetSupportedScalingCapability +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSupportedScalingCapability_t)( + ctl_display_output_handle_t, + ctl_scaling_caps_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetCurrentScaling +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetCurrentScaling_t)( + ctl_display_output_handle_t, + ctl_scaling_settings_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlSetCurrentScaling +typedef ctl_result_t (CTL_APICALL *ctl_pfnSetCurrentScaling_t)( + ctl_display_output_handle_t, + ctl_scaling_settings_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetLACEConfig +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetLACEConfig_t)( + ctl_display_output_handle_t, + ctl_lace_config_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlSetLACEConfig +typedef ctl_result_t (CTL_APICALL *ctl_pfnSetLACEConfig_t)( + ctl_display_output_handle_t, + ctl_lace_config_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlSoftwarePSR +typedef ctl_result_t (CTL_APICALL *ctl_pfnSoftwarePSR_t)( + ctl_display_output_handle_t, + ctl_sw_psr_settings_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetIntelArcSyncInfoForMonitor +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetIntelArcSyncInfoForMonitor_t)( + ctl_display_output_handle_t, + ctl_intel_arc_sync_monitor_params_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetIntelArcSyncProfile +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetIntelArcSyncProfile_t)( + ctl_display_output_handle_t, + ctl_intel_arc_sync_profile_params_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlSetIntelArcSyncProfile +typedef ctl_result_t (CTL_APICALL *ctl_pfnSetIntelArcSyncProfile_t)( + ctl_display_output_handle_t, + ctl_intel_arc_sync_profile_params_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlEdidManagement +typedef ctl_result_t (CTL_APICALL *ctl_pfnEdidManagement_t)( + ctl_display_output_handle_t, + ctl_edid_management_args_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetSetCustomMode +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSetCustomMode_t)( + ctl_display_output_handle_t, + ctl_get_set_custom_mode_args_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetSetCombinedDisplay +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSetCombinedDisplay_t)( + ctl_device_adapter_handle_t, + ctl_combined_display_args_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetSetDisplayGenlock +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSetDisplayGenlock_t)( + ctl_device_adapter_handle_t*, + ctl_genlock_args_t*, + uint32_t, + ctl_device_adapter_handle_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetVblankTimestamp +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetVblankTimestamp_t)( + ctl_display_output_handle_t, + ctl_vblank_ts_args_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlLinkDisplayAdapters +typedef ctl_result_t (CTL_APICALL *ctl_pfnLinkDisplayAdapters_t)( + ctl_device_adapter_handle_t, + ctl_lda_args_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlUnlinkDisplayAdapters +typedef ctl_result_t (CTL_APICALL *ctl_pfnUnlinkDisplayAdapters_t)( + ctl_device_adapter_handle_t + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetLinkedDisplayAdapters +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetLinkedDisplayAdapters_t)( + ctl_device_adapter_handle_t, + ctl_lda_args_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetSetDynamicContrastEnhancement +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSetDynamicContrastEnhancement_t)( + ctl_display_output_handle_t, + ctl_dce_args_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)( + ctl_device_adapter_handle_t, + uint32_t*, + ctl_engine_handle_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlEngineGetProperties +typedef ctl_result_t (CTL_APICALL *ctl_pfnEngineGetProperties_t)( + ctl_engine_handle_t, + ctl_engine_properties_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlEngineGetActivity +typedef ctl_result_t (CTL_APICALL *ctl_pfnEngineGetActivity_t)( + ctl_engine_handle_t, + ctl_engine_stats_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlEnumFans +typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumFans_t)( + ctl_device_adapter_handle_t, + uint32_t*, + ctl_fan_handle_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlFanGetProperties +typedef ctl_result_t (CTL_APICALL *ctl_pfnFanGetProperties_t)( + ctl_fan_handle_t, + ctl_fan_properties_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlFanGetConfig +typedef ctl_result_t (CTL_APICALL *ctl_pfnFanGetConfig_t)( + ctl_fan_handle_t, + ctl_fan_config_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlFanSetDefaultMode +typedef ctl_result_t (CTL_APICALL *ctl_pfnFanSetDefaultMode_t)( + ctl_fan_handle_t + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlFanSetFixedSpeedMode +typedef ctl_result_t (CTL_APICALL *ctl_pfnFanSetFixedSpeedMode_t)( + ctl_fan_handle_t, + const ctl_fan_speed_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlFanSetSpeedTableMode +typedef ctl_result_t (CTL_APICALL *ctl_pfnFanSetSpeedTableMode_t)( + ctl_fan_handle_t, + const ctl_fan_speed_table_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlFanGetState +typedef ctl_result_t (CTL_APICALL *ctl_pfnFanGetState_t)( + ctl_fan_handle_t, + ctl_fan_speed_units_t, + int32_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)( + ctl_device_adapter_handle_t, + uint32_t*, + ctl_freq_handle_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlFrequencyGetProperties +typedef ctl_result_t (CTL_APICALL *ctl_pfnFrequencyGetProperties_t)( + ctl_freq_handle_t, + ctl_freq_properties_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlFrequencyGetAvailableClocks +typedef ctl_result_t (CTL_APICALL *ctl_pfnFrequencyGetAvailableClocks_t)( + ctl_freq_handle_t, + uint32_t*, + double* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlFrequencyGetRange +typedef ctl_result_t (CTL_APICALL *ctl_pfnFrequencyGetRange_t)( + ctl_freq_handle_t, + ctl_freq_range_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlFrequencySetRange +typedef ctl_result_t (CTL_APICALL *ctl_pfnFrequencySetRange_t)( + ctl_freq_handle_t, + const ctl_freq_range_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlFrequencyGetState +typedef ctl_result_t (CTL_APICALL *ctl_pfnFrequencyGetState_t)( + ctl_freq_handle_t, + ctl_freq_state_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlFrequencyGetThrottleTime +typedef ctl_result_t (CTL_APICALL *ctl_pfnFrequencyGetThrottleTime_t)( + ctl_freq_handle_t, + ctl_freq_throttle_time_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)( + ctl_device_adapter_handle_t, + ctl_video_processing_feature_caps_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlGetSetVideoProcessingFeature +typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSetVideoProcessingFeature_t)( + ctl_device_adapter_handle_t, + ctl_video_processing_feature_getset_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlEnumMemoryModules +typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumMemoryModules_t)( + ctl_device_adapter_handle_t, + uint32_t*, + ctl_mem_handle_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlMemoryGetProperties +typedef ctl_result_t (CTL_APICALL *ctl_pfnMemoryGetProperties_t)( + ctl_mem_handle_t, + ctl_mem_properties_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlMemoryGetState +typedef ctl_result_t (CTL_APICALL *ctl_pfnMemoryGetState_t)( + ctl_mem_handle_t, + ctl_mem_state_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlMemoryGetBandwidth +typedef ctl_result_t (CTL_APICALL *ctl_pfnMemoryGetBandwidth_t)( + ctl_mem_handle_t, + ctl_mem_bandwidth_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockGetProperties +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockGetProperties_t)( + ctl_device_adapter_handle_t, + ctl_oc_properties_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockWaiverSet +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockWaiverSet_t)( + ctl_device_adapter_handle_t + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockGpuFrequencyOffsetGet +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockGpuFrequencyOffsetGet_t)( + ctl_device_adapter_handle_t, + double* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockGpuFrequencyOffsetSet +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockGpuFrequencyOffsetSet_t)( + ctl_device_adapter_handle_t, + double + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockGpuVoltageOffsetGet +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockGpuVoltageOffsetGet_t)( + ctl_device_adapter_handle_t, + double* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockGpuVoltageOffsetSet +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockGpuVoltageOffsetSet_t)( + ctl_device_adapter_handle_t, + double + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockGpuLockGet +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockGpuLockGet_t)( + ctl_device_adapter_handle_t, + ctl_oc_vf_pair_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockGpuLockSet +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockGpuLockSet_t)( + ctl_device_adapter_handle_t, + ctl_oc_vf_pair_t + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockVramFrequencyOffsetGet +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockVramFrequencyOffsetGet_t)( + ctl_device_adapter_handle_t, + double* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockVramFrequencyOffsetSet +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockVramFrequencyOffsetSet_t)( + ctl_device_adapter_handle_t, + double + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockVramVoltageOffsetGet +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockVramVoltageOffsetGet_t)( + ctl_device_adapter_handle_t, + double* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockVramVoltageOffsetSet +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockVramVoltageOffsetSet_t)( + ctl_device_adapter_handle_t, + double + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockPowerLimitGet +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockPowerLimitGet_t)( + ctl_device_adapter_handle_t, + double* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockPowerLimitSet +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockPowerLimitSet_t)( + ctl_device_adapter_handle_t, + double + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockTemperatureLimitGet +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockTemperatureLimitGet_t)( + ctl_device_adapter_handle_t, + double* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockTemperatureLimitSet +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockTemperatureLimitSet_t)( + ctl_device_adapter_handle_t, + double + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlPowerTelemetryGet +typedef ctl_result_t (CTL_APICALL *ctl_pfnPowerTelemetryGet_t)( + ctl_device_adapter_handle_t, + ctl_power_telemetry_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlOverclockResetToDefault +typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockResetToDefault_t)( + ctl_device_adapter_handle_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)( + ctl_device_adapter_handle_t, + ctl_pci_properties_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlPciGetState +typedef ctl_result_t (CTL_APICALL *ctl_pfnPciGetState_t)( + ctl_device_adapter_handle_t, + ctl_pci_state_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlEnumPowerDomains +typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumPowerDomains_t)( + ctl_device_adapter_handle_t, + uint32_t*, + ctl_pwr_handle_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlPowerGetProperties +typedef ctl_result_t (CTL_APICALL *ctl_pfnPowerGetProperties_t)( + ctl_pwr_handle_t, + ctl_power_properties_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlPowerGetEnergyCounter +typedef ctl_result_t (CTL_APICALL *ctl_pfnPowerGetEnergyCounter_t)( + ctl_pwr_handle_t, + ctl_power_energy_counter_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlPowerGetLimits +typedef ctl_result_t (CTL_APICALL *ctl_pfnPowerGetLimits_t)( + ctl_pwr_handle_t, + ctl_power_limits_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlPowerSetLimits +typedef ctl_result_t (CTL_APICALL *ctl_pfnPowerSetLimits_t)( + ctl_pwr_handle_t, + const ctl_power_limits_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlEnumTemperatureSensors +typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumTemperatureSensors_t)( + ctl_device_adapter_handle_t, + uint32_t*, + ctl_temp_handle_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlTemperatureGetProperties +typedef ctl_result_t (CTL_APICALL *ctl_pfnTemperatureGetProperties_t)( + ctl_temp_handle_t, + ctl_temp_properties_t* + ); + + +/////////////////////////////////////////////////////////////////////////////// +/// @brief Function-pointer for ctlTemperatureGetState +typedef ctl_result_t (CTL_APICALL *ctl_pfnTemperatureGetState_t)( + ctl_temp_handle_t, + double* + ); + + +#if defined(__cplusplus) +} // extern "C" +#endif + +#endif // _CTL_API_H \ No newline at end of file From e7d9e7c269f9cd368d0779fd47abe00b7ec0e0f6 Mon Sep 17 00:00:00 2001 From: Chili Date: Sat, 14 Mar 2026 07:07:00 +0900 Subject: [PATCH 04/42] igcl dumping verbose --- .../ControlLib/igcl/IgclTelemetryProvider.cpp | 66 ++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp index 89227fc6..e4558e97 100644 --- a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp @@ -4,6 +4,7 @@ #include "../Exceptions.h" #include "../Logging.h" +#include "../../CommonUtilities/ref/GeneratedReflection.h" #include #include @@ -13,6 +14,7 @@ using namespace pmon; using namespace util; +using v = log::V; namespace pmon::tel::igcl { @@ -36,6 +38,8 @@ namespace pmon::tel::igcl } throw Except("Unable to initialize Intel Graphics Control Library"); } + pmlog_verb(v::tele_gpu)("ctlInit input args") + .pmwatch(ref::DumpGenerated(ctlInitArgs)); std::vector handles{}; { @@ -45,6 +49,8 @@ namespace pmon::tel::igcl pmlog_error("ctlEnumerateDevices(count) failed").code(enumCountResult); throw std::runtime_error{ "IGCL device enumeration (count) failed" }; } + pmlog_verb(v::tele_gpu)("ctlEnumerateDevices(count) output") + .pmwatch(count); handles.resize((size_t)count); const auto enumListResult = ctlEnumerateDevices(apiHandle_, &count, handles.data()); @@ -62,12 +68,12 @@ namespace pmon::tel::igcl } auto& device = emplaceResult.first->second; + device.providerDeviceId = providerDeviceId; if (!TryInitializeDevice_(device, handle)) { devicesById_.erase(emplaceResult.first); continue; } - device.providerDeviceId = providerDeviceId; device.caps = BuildCapsForDevice_(device); ++nextProviderDeviceId_; } @@ -190,6 +196,12 @@ namespace pmon::tel::igcl pmlog_error("ctlGetDeviceProperties failed").code(propertiesResult); return false; } + pmlog_verb(v::tele_gpu)("ctlGetDeviceProperties output") + .pmwatch(device.properties.name) + .pmwatch(device.providerDeviceId) + .pmwatch(ref::DumpGenerated(device.properties)) + .pmwatch(device.deviceLuid.HighPart) + .pmwatch(device.deviceLuid.LowPart); if (device.properties.device_type != CTL_DEVICE_TYPE_GRAPHICS) { return false; @@ -200,6 +212,10 @@ namespace pmon::tel::igcl device.fingerprint.deviceName = device.properties.name; device.isAlchemist = std::regex_search(device.fingerprint.deviceName, std::regex{ R"(Arc.*A\d{3})" }); + pmlog_verb(v::tele_gpu)("Alchemist detection") + .pmwatch(device.fingerprint.deviceName) + .pmwatch(device.providerDeviceId) + .pmwatch(device.isAlchemist); EnumerateMemoryModules_(device); EnumeratePowerDomains_(device); @@ -227,6 +243,10 @@ namespace pmon::tel::igcl device.memoryModules.clear(); return; } + pmlog_verb(v::tele_gpu)("ctlEnumMemoryModules output") + .pmwatch(device.fingerprint.deviceName) + .pmwatch(device.providerDeviceId) + .pmwatch(ref::DumpGenerated(device.memoryModules)); } void IgclTelemetryProvider::EnumeratePowerDomains_(DeviceState_& device) const @@ -248,6 +268,10 @@ namespace pmon::tel::igcl device.powerDomains.clear(); return; } + pmlog_verb(v::tele_gpu)("ctlEnumPowerDomains(output)") + .pmwatch(device.fingerprint.deviceName) + .pmwatch(device.providerDeviceId) + .pmwatch(ref::DumpGenerated(device.powerDomains)); } void IgclTelemetryProvider::EnumerateFans_(DeviceState_& device) const @@ -290,6 +314,11 @@ namespace pmon::tel::igcl .pmwatch(device.fingerprint.deviceName).pmwatch(iFan); continue; } + pmlog_verb(v::tele_gpu)("ctlFanGetProperties output") + .pmwatch(device.fingerprint.deviceName) + .pmwatch(device.providerDeviceId) + .pmwatch(iFan) + .pmwatch(ref::DumpGenerated(fanProperties)); device.maxFanSpeedsRpm[(size_t)iFan] = fanProperties.maxRPM; } @@ -465,6 +494,9 @@ namespace pmon::tel::igcl .Version = 1, }; + pmlog_verb(v::tele_gpu)("telemetry poll tick") + .pmwatch(device.fingerprint.deviceName) + .pmwatch(device.providerDeviceId); const auto pollResult = ctlPowerTelemetryGet(device.handle, ¤tSample); if (pollResult != CTL_RESULT_SUCCESS) { pmlog_warn("ctlPowerTelemetryGet failed").code(pollResult).every(std::chrono::seconds{ 60 }) @@ -474,6 +506,10 @@ namespace pmon::tel::igcl .Version = 1, }; } + pmlog_verb(v::tele_gpu)("ctlPowerTelemetryGet output") + .pmwatch(device.fingerprint.deviceName) + .pmwatch(device.providerDeviceId) + .pmwatch(ref::DumpGenerated(currentSample)); device.telemetryEndpointCache.Store(requestQpc, currentSample); return device.telemetryEndpointCache.output; @@ -502,6 +538,10 @@ namespace pmon::tel::igcl pmlog_warn("ctlMemoryGetState failed").code(result).every(std::chrono::seconds{ 60 }) .pmwatch(device.fingerprint.deviceName); } + pmlog_verb(v::tele_gpu)("ctlMemoryGetState output") + .pmwatch(device.fingerprint.deviceName) + .pmwatch(device.providerDeviceId) + .pmwatch(ref::DumpGenerated(memoryState)); } if (!hasValue) { @@ -528,12 +568,20 @@ namespace pmon::tel::igcl const auto result = ctlMemoryGetBandwidth(device.memoryModules[0], &memoryBandwidth); if (result == CTL_RESULT_SUCCESS) { device.gpuMemMaxBwCacheValueBps = memoryBandwidth.maxBandwidth; + pmlog_verb(v::tele_gpu)("ctlMemoryGetBandwidth output") + .pmwatch(device.fingerprint.deviceName) + .pmwatch(device.providerDeviceId) + .pmwatch(ref::DumpGenerated(memoryBandwidth)); return memoryBandwidth; } else { pmlog_warn("ctlMemoryGetBandwidth failed").code(result).every(std::chrono::seconds{ 60 }) .pmwatch(device.fingerprint.deviceName); } + pmlog_verb(v::tele_gpu)("ctlMemoryGetBandwidth output") + .pmwatch(device.fingerprint.deviceName) + .pmwatch(device.providerDeviceId) + .pmwatch(ref::DumpGenerated(memoryBandwidth)); } (void)requestQpc; @@ -551,6 +599,10 @@ namespace pmon::tel::igcl if (!device.powerDomains.empty()) { const auto result = ctlPowerGetLimits(device.powerDomains[0], &powerLimits); if (result == CTL_RESULT_SUCCESS) { + pmlog_verb(v::tele_gpu)("ctlPowerGetLimits output") + .pmwatch(device.fingerprint.deviceName) + .pmwatch(device.providerDeviceId) + .pmwatch(ref::DumpGenerated(powerLimits)); return powerLimits; } else { @@ -692,11 +744,17 @@ namespace pmon::tel::igcl case PM_METRIC_GPU_MEM_WRITE_BANDWIDTH: ValidateScalarMetricIndex_(metricId, arrayIndex); if (device.useNewBandwidthTelemetry) { + pmlog_verb(v::tele_gpu)("ctlPowerTelemetryGet VRAM bandwidth V1 path") + .pmwatch(device.fingerprint.deviceName) + .pmwatch(device.providerDeviceId); if (TryGetInstantaneousTelemetryItem_(currentSample.vramWriteBandwidth, value)) { return ConvertMegabytesPerSecondToBitsPerSecond_(value); } device.useNewBandwidthTelemetry = false; } + pmlog_verb(v::tele_gpu)("ctlPowerTelemetryGet VRAM bandwidth counter path") + .pmwatch(device.fingerprint.deviceName) + .pmwatch(device.providerDeviceId); if (pPreviousSample && TryGetUsageTelemetryItem_( device, @@ -711,11 +769,17 @@ namespace pmon::tel::igcl case PM_METRIC_GPU_MEM_READ_BANDWIDTH: ValidateScalarMetricIndex_(metricId, arrayIndex); if (device.useNewBandwidthTelemetry) { + pmlog_verb(v::tele_gpu)("ctlPowerTelemetryGet VRAM bandwidth V1 path") + .pmwatch(device.fingerprint.deviceName) + .pmwatch(device.providerDeviceId); if (TryGetInstantaneousTelemetryItem_(currentSample.vramReadBandwidth, value)) { return ConvertMegabytesPerSecondToBitsPerSecond_(value); } device.useNewBandwidthTelemetry = false; } + pmlog_verb(v::tele_gpu)("ctlPowerTelemetryGet VRAM bandwidth counter path") + .pmwatch(device.fingerprint.deviceName) + .pmwatch(device.providerDeviceId); if (pPreviousSample && TryGetUsageTelemetryItem_( device, From 06737953f89a4b8206ae39c323aafcc276550e20 Mon Sep 17 00:00:00 2001 From: Chili Date: Sat, 14 Mar 2026 07:35:25 +0900 Subject: [PATCH 05/42] better sample handling w/ double buffer etc. --- IntelPresentMon/ControlLib/ControlLib.vcxproj | 2 +- .../ControlLib/ControlLib.vcxproj.filters | 2 +- .../{TelemetryCache.h => EndpointCache.h} | 7 +- .../ControlLib/igcl/IgclTelemetryProvider.cpp | 169 ++++++++++-------- .../ControlLib/igcl/IgclTelemetryProvider.h | 36 +++- 5 files changed, 128 insertions(+), 88 deletions(-) rename IntelPresentMon/ControlLib/{TelemetryCache.h => EndpointCache.h} (69%) diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj b/IntelPresentMon/ControlLib/ControlLib.vcxproj index 7188846d..97b24bd9 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj @@ -130,7 +130,7 @@ - + diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters index 76c2a630..40a9a549 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters @@ -81,7 +81,7 @@ - + Intel diff --git a/IntelPresentMon/ControlLib/TelemetryCache.h b/IntelPresentMon/ControlLib/EndpointCache.h similarity index 69% rename from IntelPresentMon/ControlLib/TelemetryCache.h rename to IntelPresentMon/ControlLib/EndpointCache.h index 7ec0cb16..c3201e13 100644 --- a/IntelPresentMon/ControlLib/TelemetryCache.h +++ b/IntelPresentMon/ControlLib/EndpointCache.h @@ -12,16 +12,15 @@ namespace pmon::tele T output{}; int64_t requestQpc = 0; - bool HasValue(int64_t candidateRequestQpc) const noexcept + bool Matches(int64_t candidateRequestQpc) const noexcept { return requestQpc != 0 && candidateRequestQpc != 0 && requestQpc == candidateRequestQpc; } - void Store(int64_t newRequestQpc, const T& newOutput) noexcept + bool Empty() const noexcept { - output = newOutput; - requestQpc = newRequestQpc; + return requestQpc == 0; } void Clear() noexcept diff --git a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp index e4558e97..f86147f8 100644 --- a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp @@ -18,9 +18,57 @@ using v = log::V; namespace pmon::tel::igcl { - namespace + IgclTelemetryProvider::TelemetrySampleBuffer_::TelemetrySampleBuffer_() noexcept + : samples_{ MakeEmptySample_(), MakeEmptySample_() } + {} + + bool IgclTelemetryProvider::TelemetrySampleBuffer_::Matches(int64_t requestQpc) const noexcept + { + return hasCurrent_ && requestQpc != 0 && requestQpcs_[currentIndex_] == requestQpc; + } + + ctl_power_telemetry_t& IgclTelemetryProvider::TelemetrySampleBuffer_::PrepareForWrite(int64_t requestQpc) noexcept + { + if (requestQpc != 0 && hasCurrent_ && + requestQpcs_[currentIndex_] != 0 && requestQpcs_[currentIndex_] != requestQpc) { + previousIndex_ = currentIndex_; + currentIndex_ = currentIndex_ == 0 ? 1u : 0u; + hasPrevious_ = true; + } + + hasCurrent_ = true; + requestQpcs_[currentIndex_] = requestQpc; + samples_[currentIndex_] = MakeEmptySample_(); + return samples_[currentIndex_]; + } + + const ctl_power_telemetry_t& IgclTelemetryProvider::TelemetrySampleBuffer_::Current() const noexcept + { + return samples_[currentIndex_]; + } + + const ctl_power_telemetry_t* IgclTelemetryProvider::TelemetrySampleBuffer_::Previous() const noexcept + { + if (!hasPrevious_) { + return nullptr; + } + return &samples_[previousIndex_]; + } + + int64_t IgclTelemetryProvider::TelemetrySampleBuffer_::PreviousRequestQpc() const noexcept { - constexpr uint32_t kMaxFanCount_ = CTL_FAN_COUNT; + if (!hasPrevious_) { + return 0; + } + return requestQpcs_[previousIndex_]; + } + + ctl_power_telemetry_t IgclTelemetryProvider::TelemetrySampleBuffer_::MakeEmptySample_() noexcept + { + return { + .Size = sizeof(ctl_power_telemetry_t), + .Version = 1, + }; } IgclTelemetryProvider::IgclTelemetryProvider() @@ -125,7 +173,7 @@ namespace pmon::tel::igcl case PM_METRIC_GPU_SUSTAINED_POWER_LIMIT: { ValidateScalarMetricIndex_(metricId, arrayIndex); - const auto limits = PollPowerLimitsEndpoint_(device, requestQpc); + const auto limits = PollPowerLimitsEndpoint_(device); if (!limits || !limits->sustainedPowerLimit.enabled) { return 0.0; } @@ -134,34 +182,34 @@ namespace pmon::tel::igcl case PM_METRIC_GPU_MEM_SIZE: { ValidateScalarMetricIndex_(metricId, arrayIndex); - const auto memState = PollMemoryStateEndpoint_(device, requestQpc); - if (!memState) { + const auto* pMemState = PollMemoryStateEndpoint_(device, requestQpc); + if (pMemState == nullptr) { return (uint64_t)0; } - return (uint64_t)memState->size; + return (uint64_t)pMemState->size; } case PM_METRIC_GPU_MEM_USED: { ValidateScalarMetricIndex_(metricId, arrayIndex); - const auto memState = PollMemoryStateEndpoint_(device, requestQpc); - if (!memState) { + const auto* pMemState = PollMemoryStateEndpoint_(device, requestQpc); + if (pMemState == nullptr) { return (uint64_t)0; } - return (uint64_t)(memState->size - memState->free); + return (uint64_t)(pMemState->size - pMemState->free); } case PM_METRIC_GPU_MEM_UTILIZATION: { ValidateScalarMetricIndex_(metricId, arrayIndex); - const auto memState = PollMemoryStateEndpoint_(device, requestQpc); - if (!memState || memState->size == 0) { + const auto* pMemState = PollMemoryStateEndpoint_(device, requestQpc); + if (pMemState == nullptr || pMemState->size == 0) { return 0.0; } - return 100.0 * ((double)(memState->size - memState->free) / (double)memState->size); + return 100.0 * ((double)(pMemState->size - pMemState->free) / (double)pMemState->size); } case PM_METRIC_GPU_MEM_MAX_BANDWIDTH: { ValidateScalarMetricIndex_(metricId, arrayIndex); - const auto memBandwidth = PollMemoryBandwidthEndpoint_(device, requestQpc); + const auto memBandwidth = PollMemoryBandwidthEndpoint_(device); if (!memBandwidth) { return (uint64_t)0; } @@ -277,7 +325,7 @@ namespace pmon::tel::igcl void IgclTelemetryProvider::EnumerateFans_(DeviceState_& device) const { device.maxFanSpeedsRpm.clear(); - device.maxFanSpeedsRpm.resize((size_t)kMaxFanCount_, 0); + device.maxFanSpeedsRpm.resize((size_t)CTL_FAN_COUNT, 0); uint32_t fanCount = 0; const auto enumCountResult = ctlEnumFans(device.handle, &fanCount, nullptr); @@ -300,7 +348,7 @@ namespace pmon::tel::igcl return; } - const auto fanCountToRead = (uint32_t)std::min((size_t)fanCount, (size_t)kMaxFanCount_); + const auto fanCountToRead = (uint32_t)std::min((size_t)fanCount, (size_t)CTL_FAN_COUNT); for (uint32_t iFan = 0; iFan < fanCountToRead; ++iFan) { const auto hFan = fanHandles[(size_t)iFan]; if (hFan == nullptr) { @@ -332,26 +380,25 @@ namespace pmon::tel::igcl caps.Set(PM_METRIC_GPU_VENDOR, 1); caps.Set(PM_METRIC_GPU_NAME, 1); - const auto powerLimits = PollPowerLimitsEndpoint_(device, 0); + const auto powerLimits = PollPowerLimitsEndpoint_(device); if (powerLimits && powerLimits->sustainedPowerLimit.enabled) { caps.Set(PM_METRIC_GPU_SUSTAINED_POWER_LIMIT, 1); } - const auto memoryState = PollMemoryStateEndpoint_(device, 0); - if (memoryState) { + const auto* pMemoryState = PollMemoryStateEndpoint_(device, 0); + if (pMemoryState != nullptr) { caps.Set(PM_METRIC_GPU_MEM_SIZE, 1); caps.Set(PM_METRIC_GPU_MEM_USED, 1); caps.Set(PM_METRIC_GPU_MEM_UTILIZATION, 1); - (void)memoryState; } - const auto memoryBandwidth = PollMemoryBandwidthEndpoint_(device, 0); + const auto memoryBandwidth = PollMemoryBandwidthEndpoint_(device); if (memoryBandwidth) { caps.Set(PM_METRIC_GPU_MEM_MAX_BANDWIDTH, 1); device.gpuMemMaxBwCacheValueBps = memoryBandwidth->maxBandwidth; } - const auto sample = PollTelemetryEndpoint_(device, 0); + const auto& sample = PollTelemetryEndpoint_(device, 0); if (IsUsageTelemetryItemSupported_(sample.gpuEnergyCounter)) { caps.Set(PM_METRIC_GPU_POWER, 1); @@ -435,11 +482,11 @@ namespace pmon::tel::igcl } device.fanSpeedCount = 0; - while (device.fanSpeedCount < kMaxFanCount_ && + while (device.fanSpeedCount < CTL_FAN_COUNT && IsInstantaneousTelemetryItemSupported_(sample.fanSpeed[(size_t)device.fanSpeedCount])) { ++device.fanSpeedCount; } - for (uint32_t iFan = device.fanSpeedCount; iFan < kMaxFanCount_; ++iFan) { + for (uint32_t iFan = device.fanSpeedCount; iFan < CTL_FAN_COUNT; ++iFan) { if (IsInstantaneousTelemetryItemSupported_(sample.fanSpeed[(size_t)iFan])) { pmlog_warn("Detected sparse fan-speed telemetry population; assuming dense indices") .pmwatch(device.fingerprint.deviceName) @@ -480,19 +527,11 @@ namespace pmon::tel::igcl DeviceState_& device, int64_t requestQpc) const { - if (requestQpc != 0 && device.telemetryEndpointCache.requestQpc == requestQpc) { - return device.telemetryEndpointCache.output; - } - - if (requestQpc != 0 && device.telemetryEndpointCache.requestQpc != 0 && - device.telemetryEndpointCache.requestQpc != requestQpc) { - device.previousTelemetryEndpointCache = device.telemetryEndpointCache; + if (device.telemetrySamples.Matches(requestQpc)) { + return device.telemetrySamples.Current(); } - ctl_power_telemetry_t currentSample{ - .Size = sizeof(ctl_power_telemetry_t), - .Version = 1, - }; + auto& currentSample = device.telemetrySamples.PrepareForWrite(requestQpc); pmlog_verb(v::tele_gpu)("telemetry poll tick") .pmwatch(device.fingerprint.deviceName) @@ -511,53 +550,41 @@ namespace pmon::tel::igcl .pmwatch(device.providerDeviceId) .pmwatch(ref::DumpGenerated(currentSample)); - device.telemetryEndpointCache.Store(requestQpc, currentSample); - return device.telemetryEndpointCache.output; + return device.telemetrySamples.Current(); } - std::optional IgclTelemetryProvider::PollMemoryStateEndpoint_( + const ctl_mem_state_t* IgclTelemetryProvider::PollMemoryStateEndpoint_( DeviceState_& device, int64_t requestQpc) const { - if (device.memoryStateEndpointCache.HasValue(requestQpc)) { - if (device.memoryStateEndpointCache.output.Size == sizeof(ctl_mem_state_t)) { - return device.memoryStateEndpointCache.output; - } - return {}; + auto& cache = device.memoryStateEndpointCache; + if (cache.Matches(requestQpc)) { + return cache.output.Size == sizeof(ctl_mem_state_t) ? &cache.output : nullptr; } - ctl_mem_state_t memoryState{ .Size = sizeof(ctl_mem_state_t) }; - bool hasValue = false; + cache.output = { .Size = sizeof(ctl_mem_state_t) }; + cache.requestQpc = requestQpc; if (!device.memoryModules.empty()) { - const auto result = ctlMemoryGetState(device.memoryModules[0], &memoryState); - if (result == CTL_RESULT_SUCCESS) { - hasValue = true; - } - else { + const auto result = ctlMemoryGetState(device.memoryModules[0], &cache.output); + if (result != CTL_RESULT_SUCCESS) { pmlog_warn("ctlMemoryGetState failed").code(result).every(std::chrono::seconds{ 60 }) .pmwatch(device.fingerprint.deviceName); + cache.output.Size = 0; } pmlog_verb(v::tele_gpu)("ctlMemoryGetState output") .pmwatch(device.fingerprint.deviceName) .pmwatch(device.providerDeviceId) - .pmwatch(ref::DumpGenerated(memoryState)); + .pmwatch(ref::DumpGenerated(cache.output)); } - - if (!hasValue) { - // Mark cached sample invalid while still memoizing the requestQpc. - memoryState.Size = 0; + else { + cache.output.Size = 0; } - device.memoryStateEndpointCache.Store(requestQpc, memoryState); - if (hasValue) { - return device.memoryStateEndpointCache.output; - } - return {}; + return cache.output.Size == sizeof(ctl_mem_state_t) ? &cache.output : nullptr; } std::optional IgclTelemetryProvider::PollMemoryBandwidthEndpoint_( - DeviceState_& device, - int64_t requestQpc) const + DeviceState_& device) const { ctl_mem_bandwidth_t memoryBandwidth{ .Size = sizeof(ctl_mem_bandwidth_t), @@ -584,13 +611,11 @@ namespace pmon::tel::igcl .pmwatch(ref::DumpGenerated(memoryBandwidth)); } - (void)requestQpc; return {}; } std::optional IgclTelemetryProvider::PollPowerLimitsEndpoint_( - DeviceState_& device, - int64_t requestQpc) const + DeviceState_& device) const { ctl_power_limits_t powerLimits{ .Size = sizeof(ctl_power_limits_t), @@ -611,7 +636,6 @@ namespace pmon::tel::igcl } } - (void)requestQpc; return {}; } @@ -622,15 +646,14 @@ namespace pmon::tel::igcl int64_t requestQpc) const { const auto& currentSample = PollTelemetryEndpoint_(device, requestQpc); - const auto& previousSampleCache = device.previousTelemetryEndpointCache; - const ctl_power_telemetry_t* pPreviousSample = nullptr; + const auto* pPreviousSample = device.telemetrySamples.Previous(); double timeDelta = 0.0; - if (previousSampleCache.requestQpc != 0 && + if (device.telemetrySamples.PreviousRequestQpc() != 0 && + pPreviousSample != nullptr && currentSample.timeStamp.type == CTL_DATA_TYPE_DOUBLE && - previousSampleCache.output.timeStamp.type == CTL_DATA_TYPE_DOUBLE) { - pPreviousSample = &previousSampleCache.output; + pPreviousSample->timeStamp.type == CTL_DATA_TYPE_DOUBLE) { timeDelta = currentSample.timeStamp.value.datadouble - - previousSampleCache.output.timeStamp.value.datadouble; + pPreviousSample->timeStamp.value.datadouble; } double value = 0.0; @@ -830,7 +853,7 @@ namespace pmon::tel::igcl case PM_METRIC_GPU_FAN_SPEED: { if (arrayIndex >= device.fanSpeedCount) { - throw Except<>{ "IGCL array index out of range" }; + throw Except<>("IGCL array index out of range"); } if (TryGetInstantaneousTelemetryItem_(currentSample.fanSpeed[(size_t)arrayIndex], value)) { return value; @@ -840,7 +863,7 @@ namespace pmon::tel::igcl case PM_METRIC_GPU_FAN_SPEED_PERCENT: { if (arrayIndex >= device.fanSpeedPercentCount) { - throw Except<>{ "IGCL array index out of range" }; + throw Except<>("IGCL array index out of range"); } if (!TryGetInstantaneousTelemetryItem_(currentSample.fanSpeed[(size_t)arrayIndex], value)) { return 0.0; diff --git a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.h b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.h index 19ff283b..5cb3fad2 100644 --- a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.h +++ b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.h @@ -4,7 +4,7 @@ #define NOMINMAX #include -#include "../TelemetryCache.h" +#include "../EndpointCache.h" #include "../TelemetryProvider.h" #include "igcl_api.h" @@ -29,6 +29,28 @@ namespace pmon::tel::igcl int64_t requestQpc) override; private: + class TelemetrySampleBuffer_ + { + public: + TelemetrySampleBuffer_() noexcept; + bool Matches(int64_t requestQpc) const noexcept; + ctl_power_telemetry_t& PrepareForWrite(int64_t requestQpc) noexcept; + const ctl_power_telemetry_t& Current() const noexcept; + const ctl_power_telemetry_t* Previous() const noexcept; + int64_t PreviousRequestQpc() const noexcept; + + private: + static ctl_power_telemetry_t MakeEmptySample_() noexcept; + + private: + ctl_power_telemetry_t samples_[2]{}; + int64_t requestQpcs_[2]{}; + uint32_t currentIndex_ = 0; + uint32_t previousIndex_ = 1; + bool hasCurrent_ = false; + bool hasPrevious_ = false; + }; + struct DeviceState_ { ProviderDeviceId providerDeviceId = 0; @@ -47,9 +69,7 @@ namespace pmon::tel::igcl bool useNewBandwidthTelemetry = true; - pmon::tele::EndpointCache telemetryEndpointCache{}; - pmon::tele::EndpointCache previousTelemetryEndpointCache{}; - + TelemetrySampleBuffer_ telemetrySamples{}; pmon::tele::EndpointCache memoryStateEndpointCache{}; // Runtime telemetry workarounds carried over from the legacy Intel path. @@ -68,15 +88,13 @@ namespace pmon::tel::igcl const ctl_power_telemetry_t& PollTelemetryEndpoint_( DeviceState_& device, int64_t requestQpc) const; - std::optional PollMemoryStateEndpoint_( + const ctl_mem_state_t* PollMemoryStateEndpoint_( DeviceState_& device, int64_t requestQpc) const; std::optional PollMemoryBandwidthEndpoint_( - DeviceState_& device, - int64_t requestQpc) const; + DeviceState_& device) const; std::optional PollPowerLimitsEndpoint_( - DeviceState_& device, - int64_t requestQpc) const; + DeviceState_& device) const; TelemetryMetricValue PollTelemetryMetric_( DeviceState_& device, From 9cebb49d143d0b09a67de49c978d11eff1b38ee7 Mon Sep 17 00:00:00 2001 From: Chili Date: Sat, 14 Mar 2026 07:52:12 +0900 Subject: [PATCH 06/42] nvapi provider draft --- IntelPresentMon/ControlLib/ControlLib.vcxproj | 2 + .../ControlLib/ControlLib.vcxproj.filters | 6 + IntelPresentMon/ControlLib/EndpointCache.h | 3 +- .../ControlLib/TelemetryCoordinator.cpp | 26 +- .../nvapi/NvapiTelemetryProvider.cpp | 475 ++++++++++++++++++ .../ControlLib/nvapi/NvapiTelemetryProvider.h | 87 ++++ 6 files changed, 595 insertions(+), 4 deletions(-) create mode 100644 IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.cpp create mode 100644 IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.h diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj b/IntelPresentMon/ControlLib/ControlLib.vcxproj index 97b24bd9..577c9324 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj @@ -122,6 +122,7 @@ + @@ -152,6 +153,7 @@ + diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters index 40a9a549..b1dc0ca0 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters @@ -40,6 +40,9 @@ Nvidia + + Nvidia + Nvidia @@ -92,6 +95,9 @@ Nvidia + + Nvidia + Nvidia diff --git a/IntelPresentMon/ControlLib/EndpointCache.h b/IntelPresentMon/ControlLib/EndpointCache.h index c3201e13..7a7e3d3c 100644 --- a/IntelPresentMon/ControlLib/EndpointCache.h +++ b/IntelPresentMon/ControlLib/EndpointCache.h @@ -14,8 +14,7 @@ namespace pmon::tele bool Matches(int64_t candidateRequestQpc) const noexcept { - return requestQpc != 0 && candidateRequestQpc != 0 && - requestQpc == candidateRequestQpc; + return requestQpc == candidateRequestQpc; } bool Empty() const noexcept diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp index 5d2c77a1..f5b3525f 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp @@ -1,8 +1,11 @@ // Copyright (C) 2026 Intel Corporation // SPDX-License-Identifier: MIT #include "TelemetryCoordinator.h" +#include "Exceptions.h" #include "TelemetryDeviceFingerprint.h" #include "Logging.h" +#include "igcl/IgclTelemetryProvider.h" +#include "nvapi/NvapiTelemetryProvider.h" #include "../CommonUtilities/Exception.h" #include "../CommonUtilities/Qpc.h" #include "../Interprocess/source/Interprocess.h" @@ -261,8 +264,27 @@ namespace pmon::tel void TelemetryCoordinator::TryCreateConcreteProviders_() { - // TODO: Add construction attempts for all concrete telemetry providers. - // TODO: Catch provider construction failures and continue with remaining providers. + providerPtrs_.clear(); + + try { + providerPtrs_.push_back(std::make_shared()); + } + catch (const TelemetrySubsystemAbsent&) { + pmlog_warn(util::ReportException("IGCL telemetry provider unavailable")); + } + catch (...) { + pmlog_error(util::ReportException("IGCL telemetry provider construction failed")); + } + + try { + providerPtrs_.push_back(std::make_shared()); + } + catch (const TelemetrySubsystemAbsent&) { + pmlog_warn(util::ReportException("NVAPI telemetry provider unavailable")); + } + catch (...) { + pmlog_error(util::ReportException("NVAPI telemetry provider construction failed")); + } } void TelemetryCoordinator::BuildLogicalDevicesAndRoutes_() diff --git a/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.cpp b/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.cpp new file mode 100644 index 00000000..83d76ecd --- /dev/null +++ b/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.cpp @@ -0,0 +1,475 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#include "NvapiTelemetryProvider.h" + +#include "../Exceptions.h" +#include "../Logging.h" + +#include +#include + +using namespace pmon; +using namespace util; + +namespace pmon::tel::nvapi +{ + NvapiTelemetryProvider::NvapiTelemetryProvider() + { + try { + pNvapi_ = std::make_unique(); + } + catch (const TelemetrySubsystemAbsent&) { + throw; + } + catch (...) { + pmlog_error(util::ReportException("NVAPI wrapper construction failed")); + throw Except("Unable to initialize NVIDIA API"); + } + + std::vector handles((size_t)NVAPI_MAX_PHYSICAL_GPUS); + NvU32 count = (NvU32)handles.size(); + const auto enumResult = pNvapi_->EnumPhysicalGPUs(handles.data(), &count); + if (enumResult == NVAPI_NVIDIA_DEVICE_NOT_FOUND) { + return; + } + if (!pwr::nv::NvapiWrapper::Ok(enumResult)) { + pmlog_error("NvAPI_EnumPhysicalGPUs failed").code(enumResult); + throw Except<>("NVAPI physical GPU enumeration failed"); + } + + handles.resize((size_t)count); + for (const auto handle : handles) { + const auto providerDeviceId = nextProviderDeviceId_; + const auto emplaceResult = devicesById_.try_emplace(providerDeviceId); + if (!emplaceResult.second) { + throw Except<>("Duplicate NVAPI provider device id encountered"); + } + + auto& device = emplaceResult.first->second; + device.providerDeviceId = providerDeviceId; + if (!TryInitializeDevice_(device, handle)) { + devicesById_.erase(emplaceResult.first); + continue; + } + + device.caps = BuildCapsForDevice_(device); + ++nextProviderDeviceId_; + } + } + + ProviderCapabilityMap NvapiTelemetryProvider::GetCaps() + { + ProviderCapabilityMap capsByDeviceId{}; + for (const auto& entry : devicesById_) { + capsByDeviceId.emplace(entry.first, entry.second.caps); + } + return capsByDeviceId; + } + + const TelemetryDeviceFingerprint& NvapiTelemetryProvider::GetFingerPrint( + ProviderDeviceId providerDeviceId) const + { + const auto iDevice = devicesById_.find(providerDeviceId); + if (iDevice == devicesById_.end()) { + throw Except<>("NVAPI provider device not found"); + } + return iDevice->second.fingerprint; + } + + TelemetryMetricValue NvapiTelemetryProvider::PollMetric( + ProviderDeviceId providerDeviceId, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) + { + const auto iDevice = devicesById_.find(providerDeviceId); + if (iDevice == devicesById_.end()) { + throw Except<>("NVAPI provider device not found"); + } + + auto& device = iDevice->second; + + switch (metricId) { + case PM_METRIC_GPU_VENDOR: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return (int)device.fingerprint.vendor; + case PM_METRIC_GPU_NAME: + throw Except<>("PM_METRIC_GPU_NAME is static-only and is not served by poll path"); + default: + return PollNvapiMetric_(device, metricId, arrayIndex, requestQpc); + } + } + + void NvapiTelemetryProvider::ValidateScalarMetricIndex_(PM_METRIC metricId, uint32_t arrayIndex) + { + if (arrayIndex != 0) { + throw Except<>("NVAPI scalar metric queried with nonzero array index"); + } + (void)metricId; + } + + bool NvapiTelemetryProvider::TryInitializeDevice_( + DeviceState_& device, + NvPhysicalGpuHandle handle) const + { + if (handle == nullptr) { + pmlog_warn("Null NVAPI physical GPU handle encountered"); + return false; + } + + device.handle = handle; + device.fingerprint.deviceType = PM_DEVICE_TYPE_GRAPHICS_ADAPTER; + device.fingerprint.vendor = PM_DEVICE_VENDOR_NVIDIA; + device.fingerprint.deviceName = "Unknown NVIDIA Adapter"; + + NvAPI_ShortString adapterName{}; + const auto fullNameResult = pNvapi_->GPU_GetFullName(device.handle, adapterName); + if (pwr::nv::NvapiWrapper::Ok(fullNameResult)) { + device.fingerprint.deviceName = adapterName; + } + else { + pmlog_warn("NvAPI_GPU_GetFullName failed").code(fullNameResult) + .pmwatch(device.providerDeviceId); + } + + NvU32 deviceId = 0; + NvU32 subSystemId = 0; + NvU32 revisionId = 0; + NvU32 extDeviceId = 0; + const auto pciResult = pNvapi_->GPU_GetPCIIdentifiers( + device.handle, &deviceId, &subSystemId, &revisionId, &extDeviceId); + if (pwr::nv::NvapiWrapper::Ok(pciResult)) { + device.fingerprint.pciDeviceId = deviceId; + device.fingerprint.pciSubSystemId = subSystemId; + } + else { + pmlog_warn("NvAPI_GPU_GetPCIIdentifiers failed").code(pciResult) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + } + + NvU32 busId = 0; + const auto busResult = pNvapi_->GPU_GetBusId(device.handle, &busId); + if (pwr::nv::NvapiWrapper::Ok(busResult)) { + device.fingerprint.pciBusId = busId; + } + else { + pmlog_warn("NvAPI_GPU_GetBusId failed").code(busResult) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + } + + (void)revisionId; + (void)extDeviceId; + + return true; + } + + ipc::MetricCapabilities NvapiTelemetryProvider::BuildCapsForDevice_(DeviceState_& device) const + { + ipc::MetricCapabilities caps{}; + + caps.Set(PM_METRIC_GPU_VENDOR, 1); + caps.Set(PM_METRIC_GPU_NAME, 1); + + double value = 0.0; + + if (const auto* pThermals = PollThermalEndpoint_(device, 0)) { + if (TryGetThermalValue_(*pThermals, NVAPI_THERMAL_TARGET_GPU, true, value)) { + caps.Set(PM_METRIC_GPU_TEMPERATURE, 1); + } + if (TryGetThermalValue_(*pThermals, NVAPI_THERMAL_TARGET_MEMORY, false, value)) { + caps.Set(PM_METRIC_GPU_MEM_TEMPERATURE, 1); + } + } + + if (const auto* pClocks = PollClockEndpoint_(device, 0)) { + if (TryGetClockValue_(*pClocks, NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS, value)) { + caps.Set(PM_METRIC_GPU_FREQUENCY, 1); + } + if (TryGetClockValue_(*pClocks, NVAPI_GPU_PUBLIC_CLOCK_MEMORY, value)) { + caps.Set(PM_METRIC_GPU_MEM_FREQUENCY, 1); + } + } + + if (const auto* pUtilization = PollUtilizationEndpoint_(device, 0)) { + if (TryGetUtilizationValue_( + *pUtilization, pwr::nv::NVAPI_GPU_UTILIZATION_DOMAIN_GPU, value)) { + caps.Set(PM_METRIC_GPU_UTILIZATION, 1); + } + if (TryGetUtilizationValue_( + *pUtilization, pwr::nv::NVAPI_GPU_UTILIZATION_DOMAIN_VID, value)) { + caps.Set(PM_METRIC_GPU_MEDIA_UTILIZATION, 1); + } + } + + if (PollTachEndpoint_(device, 0) != nullptr) { + caps.Set(PM_METRIC_GPU_FAN_SPEED, 1); + } + + return caps; + } + + const NV_GPU_THERMAL_SETTINGS* NvapiTelemetryProvider::PollThermalEndpoint_( + DeviceState_& device, + int64_t requestQpc) const + { + auto& cache = device.thermalEndpointCache; + if (cache.Matches(requestQpc)) { + return cache.output.version == NV_GPU_THERMAL_SETTINGS_VER_2 ? &cache.output : nullptr; + } + + cache.output = { + .version = NV_GPU_THERMAL_SETTINGS_VER_2, + }; + cache.requestQpc = requestQpc; + + const auto result = pNvapi_->GPU_GetThermalSettings( + device.handle, NVAPI_THERMAL_TARGET_ALL, &cache.output); + if (!pwr::nv::NvapiWrapper::Ok(result)) { + pmlog_warn("NvAPI_GPU_GetThermalSettings failed").code(result).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + cache.output.version = 0; + return nullptr; + } + + return &cache.output; + } + + const NV_GPU_CLOCK_FREQUENCIES* NvapiTelemetryProvider::PollClockEndpoint_( + DeviceState_& device, + int64_t requestQpc) const + { + auto& cache = device.clockEndpointCache; + if (cache.Matches(requestQpc)) { + return cache.output.version == NV_GPU_CLOCK_FREQUENCIES_VER_3 ? &cache.output : nullptr; + } + + cache.output = { + .version = NV_GPU_CLOCK_FREQUENCIES_VER_3, + }; + cache.requestQpc = requestQpc; + + const auto result = pNvapi_->GPU_GetAllClockFrequencies(device.handle, &cache.output); + if (!pwr::nv::NvapiWrapper::Ok(result)) { + pmlog_warn("NvAPI_GPU_GetAllClockFrequencies failed").code(result).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + cache.output.version = 0; + return nullptr; + } + + return &cache.output; + } + + const NV_GPU_DYNAMIC_PSTATES_INFO_EX* NvapiTelemetryProvider::PollUtilizationEndpoint_( + DeviceState_& device, + int64_t requestQpc) const + { + auto& cache = device.utilizationEndpointCache; + if (cache.Matches(requestQpc)) { + return cache.output.version == NV_GPU_DYNAMIC_PSTATES_INFO_EX_VER ? &cache.output : nullptr; + } + + cache.output = { + .version = NV_GPU_DYNAMIC_PSTATES_INFO_EX_VER, + }; + cache.requestQpc = requestQpc; + + const auto result = pNvapi_->GPU_GetDynamicPstatesInfoEx(device.handle, &cache.output); + if (!pwr::nv::NvapiWrapper::Ok(result)) { + pmlog_warn("NvAPI_GPU_GetDynamicPstatesInfoEx failed").code(result).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + cache.output.version = 0; + return nullptr; + } + + return &cache.output; + } + + const NvU32* NvapiTelemetryProvider::PollTachEndpoint_( + DeviceState_& device, + int64_t requestQpc) const + { + auto& cache = device.tachEndpointCache; + if (cache.Matches(requestQpc)) { + return cache.output ? &*cache.output : nullptr; + } + + cache.output.reset(); + cache.requestQpc = requestQpc; + + NvU32 tach = 0; + const auto result = pNvapi_->GPU_GetTachReading(device.handle, &tach); + if (!pwr::nv::NvapiWrapper::Ok(result)) { + pmlog_warn("NvAPI_GPU_GetTachReading failed").code(result).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + return nullptr; + } + + cache.output = tach; + return &*cache.output; + } + + TelemetryMetricValue NvapiTelemetryProvider::PollNvapiMetric_( + DeviceState_& device, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) const + { + double value = 0.0; + + switch (metricId) { + case PM_METRIC_GPU_TEMPERATURE: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto* pThermals = PollThermalEndpoint_(device, requestQpc); + if (pThermals && + TryGetThermalValue_(*pThermals, NVAPI_THERMAL_TARGET_GPU, true, value)) { + return value; + } + return 0.0; + } + case PM_METRIC_GPU_MEM_TEMPERATURE: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto* pThermals = PollThermalEndpoint_(device, requestQpc); + if (pThermals && + TryGetThermalValue_(*pThermals, NVAPI_THERMAL_TARGET_MEMORY, false, value)) { + return value; + } + return 0.0; + } + case PM_METRIC_GPU_FREQUENCY: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto* pClocks = PollClockEndpoint_(device, requestQpc); + if (pClocks && + TryGetClockValue_(*pClocks, NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS, value)) { + return value; + } + return 0.0; + } + case PM_METRIC_GPU_MEM_FREQUENCY: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto* pClocks = PollClockEndpoint_(device, requestQpc); + if (pClocks && + TryGetClockValue_(*pClocks, NVAPI_GPU_PUBLIC_CLOCK_MEMORY, value)) { + return value; + } + return 0.0; + } + case PM_METRIC_GPU_FAN_SPEED: + { + if (arrayIndex != 0) { + throw Except<>("NVAPI array index out of range"); + } + const auto* pTach = PollTachEndpoint_(device, requestQpc); + if (pTach != nullptr) { + return (double)*pTach; + } + return 0.0; + } + case PM_METRIC_GPU_UTILIZATION: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto* pUtilization = PollUtilizationEndpoint_(device, requestQpc); + if (pUtilization && + TryGetUtilizationValue_( + *pUtilization, pwr::nv::NVAPI_GPU_UTILIZATION_DOMAIN_GPU, value)) { + return value; + } + return 0.0; + } + case PM_METRIC_GPU_MEDIA_UTILIZATION: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto* pUtilization = PollUtilizationEndpoint_(device, requestQpc); + if (pUtilization && + TryGetUtilizationValue_( + *pUtilization, pwr::nv::NVAPI_GPU_UTILIZATION_DOMAIN_VID, value)) { + return value; + } + return 0.0; + } + default: + throw Except<>("Unsupported metric for NVAPI provider"); + } + } + + bool NvapiTelemetryProvider::TryGetThermalValue_( + const NV_GPU_THERMAL_SETTINGS& thermalSettings, + NV_THERMAL_TARGET target, + bool requireInternalController, + double& value) + { + const auto sensorCount = (uint32_t)std::min( + (size_t)thermalSettings.count, (size_t)NVAPI_MAX_THERMAL_SENSORS_PER_GPU); + + if (requireInternalController) { + for (uint32_t i = 0; i < sensorCount; ++i) { + const auto& sensor = thermalSettings.sensor[(size_t)i]; + if (sensor.target == target && + sensor.controller == NVAPI_THERMAL_CONTROLLER_GPU_INTERNAL) { + value = (double)sensor.currentTemp; + return true; + } + } + } + + for (uint32_t i = 0; i < sensorCount; ++i) { + const auto& sensor = thermalSettings.sensor[(size_t)i]; + if (sensor.target == target && !requireInternalController) { + value = (double)sensor.currentTemp; + return true; + } + } + + value = 0.0; + return false; + } + + bool NvapiTelemetryProvider::TryGetClockValue_( + const NV_GPU_CLOCK_FREQUENCIES& clockFrequencies, + NV_GPU_PUBLIC_CLOCK_ID clockDomain, + double& value) + { + if ((size_t)clockDomain >= (size_t)NVAPI_MAX_GPU_PUBLIC_CLOCKS) { + value = 0.0; + return false; + } + + const auto& domain = clockFrequencies.domain[(size_t)clockDomain]; + if (!domain.bIsPresent) { + value = 0.0; + return false; + } + + value = (double)domain.frequency / 1000.0; + return true; + } + + bool NvapiTelemetryProvider::TryGetUtilizationValue_( + const NV_GPU_DYNAMIC_PSTATES_INFO_EX& utilization, + pwr::nv::NVAPI_GPU_UTILIZATION_DOMAIN utilizationDomain, + double& value) + { + if ((size_t)utilizationDomain >= (size_t)NVAPI_MAX_GPU_UTILIZATIONS) { + value = 0.0; + return false; + } + + const auto& domain = utilization.utilization[(size_t)utilizationDomain]; + if (!domain.bIsPresent) { + value = 0.0; + return false; + } + + value = (double)domain.percentage; + return true; + } +} diff --git a/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.h b/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.h new file mode 100644 index 00000000..65326658 --- /dev/null +++ b/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.h @@ -0,0 +1,87 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#pragma once + +#include "../EndpointCache.h" +#include "../NvapiWrapper.h" +#include "../TelemetryProvider.h" + +#include +#include +#include +#include +#include + +namespace pmon::tel::nvapi +{ + class NvapiTelemetryProvider : public TelemetryProvider + { + public: + NvapiTelemetryProvider(); + ~NvapiTelemetryProvider() override = default; + ProviderCapabilityMap GetCaps() override; + const TelemetryDeviceFingerprint& GetFingerPrint(ProviderDeviceId providerDeviceId) const override; + TelemetryMetricValue PollMetric( + ProviderDeviceId providerDeviceId, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) override; + + private: + struct DeviceState_ + { + ProviderDeviceId providerDeviceId = 0; + TelemetryDeviceFingerprint fingerprint{}; + ipc::MetricCapabilities caps{}; + + NvPhysicalGpuHandle handle = nullptr; + + pmon::tele::EndpointCache thermalEndpointCache{}; + pmon::tele::EndpointCache clockEndpointCache{}; + pmon::tele::EndpointCache utilizationEndpointCache{}; + pmon::tele::EndpointCache> tachEndpointCache{}; + }; + + static void ValidateScalarMetricIndex_(PM_METRIC metricId, uint32_t arrayIndex); + bool TryInitializeDevice_(DeviceState_& device, NvPhysicalGpuHandle handle) const; + ipc::MetricCapabilities BuildCapsForDevice_(DeviceState_& device) const; + + const NV_GPU_THERMAL_SETTINGS* PollThermalEndpoint_( + DeviceState_& device, + int64_t requestQpc) const; + const NV_GPU_CLOCK_FREQUENCIES* PollClockEndpoint_( + DeviceState_& device, + int64_t requestQpc) const; + const NV_GPU_DYNAMIC_PSTATES_INFO_EX* PollUtilizationEndpoint_( + DeviceState_& device, + int64_t requestQpc) const; + const NvU32* PollTachEndpoint_( + DeviceState_& device, + int64_t requestQpc) const; + + TelemetryMetricValue PollNvapiMetric_( + DeviceState_& device, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) const; + + static bool TryGetThermalValue_( + const NV_GPU_THERMAL_SETTINGS& thermalSettings, + NV_THERMAL_TARGET target, + bool requireInternalController, + double& value); + static bool TryGetClockValue_( + const NV_GPU_CLOCK_FREQUENCIES& clockFrequencies, + NV_GPU_PUBLIC_CLOCK_ID clockDomain, + double& value); + static bool TryGetUtilizationValue_( + const NV_GPU_DYNAMIC_PSTATES_INFO_EX& utilization, + pwr::nv::NVAPI_GPU_UTILIZATION_DOMAIN utilizationDomain, + double& value); + + private: + std::unique_ptr pNvapi_{}; + std::unordered_map devicesById_{}; + ProviderDeviceId nextProviderDeviceId_ = 1; + }; +} From 31e5a6a245b3e6d3a1f291a9c8a2a00f30d713f2 Mon Sep 17 00:00:00 2001 From: Chili Date: Sat, 14 Mar 2026 08:01:50 +0900 Subject: [PATCH 07/42] nvml draft --- IntelPresentMon/ControlLib/ControlLib.vcxproj | 2 + .../ControlLib/ControlLib.vcxproj.filters | 6 + IntelPresentMon/ControlLib/NvmlWrapper.h | 5 +- .../ControlLib/TelemetryCoordinator.cpp | 11 + IntelPresentMon/ControlLib/nvml.h | 5 +- .../ControlLib/nvml/NvmlTelemetryProvider.cpp | 287 ++++++++++++++++++ .../ControlLib/nvml/NvmlTelemetryProvider.h | 58 ++++ 7 files changed, 370 insertions(+), 4 deletions(-) create mode 100644 IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.cpp create mode 100644 IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.h diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj b/IntelPresentMon/ControlLib/ControlLib.vcxproj index 577c9324..189b880c 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj @@ -123,6 +123,7 @@ + @@ -154,6 +155,7 @@ + diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters index b1dc0ca0..07fd0667 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters @@ -43,6 +43,9 @@ Nvidia + + Nvidia + Nvidia @@ -98,6 +101,9 @@ Nvidia + + Nvidia + Nvidia diff --git a/IntelPresentMon/ControlLib/NvmlWrapper.h b/IntelPresentMon/ControlLib/NvmlWrapper.h index effc83b0..b0e1773e 100644 --- a/IntelPresentMon/ControlLib/NvmlWrapper.h +++ b/IntelPresentMon/ControlLib/NvmlWrapper.h @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Intel Corporation +// Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: MIT #pragma once #include "nvml.h" @@ -11,6 +11,7 @@ #define NVW_NVML_ENDPOINT_LIST \ X_(DeviceGetCount_v2, unsigned int*, deviceCount) \ X_(DeviceGetHandleByIndex_v2, unsigned int, index, nvmlDevice_t*, device) \ +X_(DeviceGetName, nvmlDevice_t, device, char*, name, unsigned int, length) \ X_(DeviceGetPciInfo_v3, nvmlDevice_t, device, nvmlPciInfo_t*, pci) \ X_(DeviceGetClock, nvmlDevice_t, device, nvmlClockType_t, clockType, nvmlClockId_t, clockId, unsigned int*, clockMHz) \ X_(DeviceGetMemoryInfo, nvmlDevice_t, device, nvmlMemory_t*, memory) \ @@ -54,4 +55,4 @@ namespace pwr::nv // private endpoint pointer nvmlReturn_t(*pShutdown)() = nullptr; }; -} \ No newline at end of file +} diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp index f5b3525f..a9778c51 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp @@ -6,6 +6,7 @@ #include "Logging.h" #include "igcl/IgclTelemetryProvider.h" #include "nvapi/NvapiTelemetryProvider.h" +#include "nvml/NvmlTelemetryProvider.h" #include "../CommonUtilities/Exception.h" #include "../CommonUtilities/Qpc.h" #include "../Interprocess/source/Interprocess.h" @@ -285,6 +286,16 @@ namespace pmon::tel catch (...) { pmlog_error(util::ReportException("NVAPI telemetry provider construction failed")); } + + try { + providerPtrs_.push_back(std::make_shared()); + } + catch (const TelemetrySubsystemAbsent&) { + pmlog_warn(util::ReportException("NVML telemetry provider unavailable")); + } + catch (...) { + pmlog_error(util::ReportException("NVML telemetry provider construction failed")); + } } void TelemetryCoordinator::BuildLogicalDevicesAndRoutes_() diff --git a/IntelPresentMon/ControlLib/nvml.h b/IntelPresentMon/ControlLib/nvml.h index c85383ac..ada7517b 100644 --- a/IntelPresentMon/ControlLib/nvml.h +++ b/IntelPresentMon/ControlLib/nvml.h @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Intel Corporation +// Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: MIT #pragma once @@ -95,6 +95,7 @@ union nvmlValue_t { // Opaque nvml device handle typedef struct _nvmlDevice_t* nvmlDevice_t; +#define NVML_DEVICE_NAME_BUFFER_SIZE 64 #define NVML_DEVICE_PCI_BUS_ID_BUFFER_SIZE 32 #define NVML_DEVICE_PCI_BUS_ID_BUFFER_V2_SIZE 16 @@ -128,4 +129,4 @@ struct nvmlSample_t { struct nvmlViolationTime_t { unsigned long long referenceTime; unsigned long long violationTime; -}; \ No newline at end of file +}; diff --git a/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.cpp b/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.cpp new file mode 100644 index 00000000..64b5d9cf --- /dev/null +++ b/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.cpp @@ -0,0 +1,287 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#include "NvmlTelemetryProvider.h" + +#include "../Exceptions.h" +#include "../Logging.h" + +#include + +using namespace pmon; +using namespace util; + +namespace pmon::tel::nvml +{ + NvmlTelemetryProvider::NvmlTelemetryProvider() + { + try { + pNvml_ = std::make_unique(); + } + catch (...) { + pmlog_error(util::ReportException("NVML wrapper construction failed")); + throw Except("Unable to initialize NVIDIA Management Library"); + } + + unsigned int count = 0; + const auto countResult = pNvml_->DeviceGetCount_v2(&count); + if (!pwr::nv::NvmlWrapper::Ok(countResult)) { + pmlog_error("nvmlDeviceGetCount_v2 failed").code(countResult); + throw Except<>("NVML device count query failed"); + } + + for (unsigned int i = 0; i < count; ++i) { + nvmlDevice_t handle = nullptr; + const auto handleResult = pNvml_->DeviceGetHandleByIndex_v2(i, &handle); + if (!pwr::nv::NvmlWrapper::Ok(handleResult)) { + pmlog_warn("nvmlDeviceGetHandleByIndex_v2 failed").code(handleResult) + .pmwatch(i); + continue; + } + + const auto providerDeviceId = nextProviderDeviceId_; + const auto emplaceResult = devicesById_.try_emplace(providerDeviceId); + if (!emplaceResult.second) { + throw Except<>("Duplicate NVML provider device id encountered"); + } + + auto& device = emplaceResult.first->second; + device.providerDeviceId = providerDeviceId; + if (!TryInitializeDevice_(device, handle)) { + devicesById_.erase(emplaceResult.first); + continue; + } + + device.caps = BuildCapsForDevice_(device); + ++nextProviderDeviceId_; + } + } + + ProviderCapabilityMap NvmlTelemetryProvider::GetCaps() + { + ProviderCapabilityMap capsByDeviceId{}; + for (const auto& entry : devicesById_) { + capsByDeviceId.emplace(entry.first, entry.second.caps); + } + return capsByDeviceId; + } + + const TelemetryDeviceFingerprint& NvmlTelemetryProvider::GetFingerPrint( + ProviderDeviceId providerDeviceId) const + { + const auto iDevice = devicesById_.find(providerDeviceId); + if (iDevice == devicesById_.end()) { + throw Except<>("NVML provider device not found"); + } + return iDevice->second.fingerprint; + } + + TelemetryMetricValue NvmlTelemetryProvider::PollMetric( + ProviderDeviceId providerDeviceId, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) + { + const auto iDevice = devicesById_.find(providerDeviceId); + if (iDevice == devicesById_.end()) { + throw Except<>("NVML provider device not found"); + } + + auto& device = iDevice->second; + + switch (metricId) { + case PM_METRIC_GPU_VENDOR: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return (int)device.fingerprint.vendor; + case PM_METRIC_GPU_NAME: + throw Except<>("PM_METRIC_GPU_NAME is static-only and is not served by poll path"); + case PM_METRIC_GPU_POWER: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto powerMw = PollPowerEndpoint_(device); + if (!powerMw) { + return 0.0; + } + return (double)*powerMw / 1000.0; + } + case PM_METRIC_GPU_SUSTAINED_POWER_LIMIT: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto limitMw = PollPowerLimitEndpoint_(device); + if (!limitMw) { + return 0.0; + } + return (double)*limitMw / 1000.0; + } + case PM_METRIC_GPU_MEM_SIZE: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto* pMemoryInfo = PollMemoryInfoEndpoint_(device, requestQpc); + if (pMemoryInfo == nullptr) { + return (uint64_t)0; + } + return GetLegacyTotalMemoryBytes_(*pMemoryInfo); + } + case PM_METRIC_GPU_MEM_USED: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto* pMemoryInfo = PollMemoryInfoEndpoint_(device, requestQpc); + if (pMemoryInfo == nullptr) { + return (uint64_t)0; + } + return (uint64_t)pMemoryInfo->used; + } + case PM_METRIC_GPU_MEM_UTILIZATION: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto* pMemoryInfo = PollMemoryInfoEndpoint_(device, requestQpc); + if (pMemoryInfo == nullptr) { + return 0.0; + } + + const auto totalBytes = GetLegacyTotalMemoryBytes_(*pMemoryInfo); + if (totalBytes == 0) { + return 0.0; + } + return 100.0 * ((double)pMemoryInfo->used / (double)totalBytes); + } + default: + throw Except<>("Unsupported metric for NVML provider"); + } + } + + void NvmlTelemetryProvider::ValidateScalarMetricIndex_(PM_METRIC metricId, uint32_t arrayIndex) + { + if (arrayIndex != 0) { + throw Except<>("NVML scalar metric queried with nonzero array index"); + } + (void)metricId; + } + + uint64_t NvmlTelemetryProvider::GetLegacyTotalMemoryBytes_(const nvmlMemory_t& memoryInfo) noexcept + { + return (uint64_t)memoryInfo.free; + } + + bool NvmlTelemetryProvider::TryInitializeDevice_(DeviceState_& device, nvmlDevice_t handle) const + { + if (handle == nullptr) { + pmlog_warn("Null NVML device handle encountered"); + return false; + } + + device.handle = handle; + device.fingerprint.deviceType = PM_DEVICE_TYPE_GRAPHICS_ADAPTER; + device.fingerprint.vendor = PM_DEVICE_VENDOR_NVIDIA; + device.fingerprint.deviceName = "Unknown NVIDIA Adapter"; + + char adapterName[NVML_DEVICE_NAME_BUFFER_SIZE]{}; + const auto nameResult = pNvml_->DeviceGetName( + device.handle, adapterName, (unsigned int)NVML_DEVICE_NAME_BUFFER_SIZE); + if (!pwr::nv::NvmlWrapper::Ok(nameResult)) { + pmlog_warn("nvmlDeviceGetName failed").code(nameResult) + .pmwatch(device.providerDeviceId); + } + else if (adapterName[0] != '\0') { + device.fingerprint.deviceName = adapterName; + } + else { + pmlog_warn("nvmlDeviceGetName returned empty adapter name") + .pmwatch(device.providerDeviceId); + } + + nvmlPciInfo_t pciInfo{}; + const auto pciResult = pNvml_->DeviceGetPciInfo_v3(device.handle, &pciInfo); + if (pwr::nv::NvmlWrapper::Ok(pciResult)) { + device.fingerprint.pciDeviceId = pciInfo.pciDeviceId; + device.fingerprint.pciSubSystemId = pciInfo.pciSubSystemId; + device.fingerprint.pciBusId = pciInfo.bus; + } + else { + pmlog_warn("nvmlDeviceGetPciInfo_v3 failed").code(pciResult) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + } + + return true; + } + + ipc::MetricCapabilities NvmlTelemetryProvider::BuildCapsForDevice_(DeviceState_& device) const + { + ipc::MetricCapabilities caps{}; + + caps.Set(PM_METRIC_GPU_VENDOR, 1); + caps.Set(PM_METRIC_GPU_NAME, 1); + + if (PollPowerEndpoint_(device)) { + caps.Set(PM_METRIC_GPU_POWER, 1); + } + + if (PollPowerLimitEndpoint_(device)) { + caps.Set(PM_METRIC_GPU_SUSTAINED_POWER_LIMIT, 1); + } + + if (const auto* pMemoryInfo = PollMemoryInfoEndpoint_(device, 0)) { + const auto totalBytes = GetLegacyTotalMemoryBytes_(*pMemoryInfo); + if (totalBytes != 0) { + caps.Set(PM_METRIC_GPU_MEM_SIZE, 1); + caps.Set(PM_METRIC_GPU_MEM_USED, 1); + caps.Set(PM_METRIC_GPU_MEM_UTILIZATION, 1); + } + } + + return caps; + } + + const nvmlMemory_t* NvmlTelemetryProvider::PollMemoryInfoEndpoint_( + DeviceState_& device, + int64_t requestQpc) const + { + auto& cache = device.memoryInfoEndpointCache; + if (requestQpc != 0 && cache.Matches(requestQpc)) { + return cache.output ? &*cache.output : nullptr; + } + + cache.output.reset(); + cache.requestQpc = requestQpc; + + nvmlMemory_t memoryInfo{}; + const auto result = pNvml_->DeviceGetMemoryInfo(device.handle, &memoryInfo); + if (!pwr::nv::NvmlWrapper::Ok(result)) { + pmlog_warn("nvmlDeviceGetMemoryInfo failed").code(result).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + return nullptr; + } + + cache.output = memoryInfo; + return &*cache.output; + } + + std::optional NvmlTelemetryProvider::PollPowerEndpoint_(const DeviceState_& device) const + { + unsigned int powerMw = 0; + const auto result = pNvml_->DeviceGetPowerUsage(device.handle, &powerMw); + if (!pwr::nv::NvmlWrapper::Ok(result)) { + pmlog_warn("nvmlDeviceGetPowerUsage failed").code(result).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + return {}; + } + + return powerMw; + } + + std::optional NvmlTelemetryProvider::PollPowerLimitEndpoint_(const DeviceState_& device) const + { + unsigned int limitMw = 0; + const auto result = pNvml_->DeviceGetPowerManagementLimit(device.handle, &limitMw); + if (!pwr::nv::NvmlWrapper::Ok(result)) { + pmlog_warn("nvmlDeviceGetPowerManagementLimit failed").code(result).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + return {}; + } + + return limitMw; + } +} diff --git a/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.h b/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.h new file mode 100644 index 00000000..7a34c865 --- /dev/null +++ b/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.h @@ -0,0 +1,58 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#pragma once + +#include "../EndpointCache.h" +#include "../NvmlWrapper.h" +#include "../TelemetryProvider.h" + +#include +#include +#include +#include + +namespace pmon::tel::nvml +{ + class NvmlTelemetryProvider : public TelemetryProvider + { + public: + NvmlTelemetryProvider(); + ~NvmlTelemetryProvider() override = default; + ProviderCapabilityMap GetCaps() override; + const TelemetryDeviceFingerprint& GetFingerPrint(ProviderDeviceId providerDeviceId) const override; + TelemetryMetricValue PollMetric( + ProviderDeviceId providerDeviceId, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) override; + + private: + struct DeviceState_ + { + ProviderDeviceId providerDeviceId = 0; + TelemetryDeviceFingerprint fingerprint{}; + ipc::MetricCapabilities caps{}; + + nvmlDevice_t handle = nullptr; + + pmon::tele::EndpointCache> memoryInfoEndpointCache{}; + }; + + static void ValidateScalarMetricIndex_(PM_METRIC metricId, uint32_t arrayIndex); + static uint64_t GetLegacyTotalMemoryBytes_(const nvmlMemory_t& memoryInfo) noexcept; + + bool TryInitializeDevice_(DeviceState_& device, nvmlDevice_t handle) const; + ipc::MetricCapabilities BuildCapsForDevice_(DeviceState_& device) const; + + const nvmlMemory_t* PollMemoryInfoEndpoint_( + DeviceState_& device, + int64_t requestQpc) const; + std::optional PollPowerEndpoint_(const DeviceState_& device) const; + std::optional PollPowerLimitEndpoint_(const DeviceState_& device) const; + + private: + std::unique_ptr pNvml_{}; + std::unordered_map devicesById_{}; + ProviderDeviceId nextProviderDeviceId_ = 1; + }; +} From fddb1bac0cd7fe4d1960f43e5a400789b19e7d84 Mon Sep 17 00:00:00 2001 From: Chili Date: Sat, 14 Mar 2026 15:29:40 +0900 Subject: [PATCH 08/42] draft wmi provider --- .../win/com/WbemConnection.cpp | 10 +- .../CommonUtilities/win/com/WbemConnection.h | 5 +- IntelPresentMon/ControlLib/ControlLib.vcxproj | 2 + .../ControlLib/ControlLib.vcxproj.filters | 9 + .../ControlLib/TelemetryCoordinator.cpp | 11 + .../ControlLib/wmi/WmiTelemetryProvider.cpp | 397 ++++++++++++++++++ .../ControlLib/wmi/WmiTelemetryProvider.h | 78 ++++ 7 files changed, 508 insertions(+), 4 deletions(-) create mode 100644 IntelPresentMon/ControlLib/wmi/WmiTelemetryProvider.cpp create mode 100644 IntelPresentMon/ControlLib/wmi/WmiTelemetryProvider.h diff --git a/IntelPresentMon/CommonUtilities/win/com/WbemConnection.cpp b/IntelPresentMon/CommonUtilities/win/com/WbemConnection.cpp index c978d644..032ed59f 100644 --- a/IntelPresentMon/CommonUtilities/win/com/WbemConnection.cpp +++ b/IntelPresentMon/CommonUtilities/win/com/WbemConnection.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Intel Corporation +// Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: MIT #include "WbemConnection.h" #include "Comdef.h" @@ -62,8 +62,14 @@ namespace pmon::util::win::com throw Except(); } } + + IWbemServices* WbemConnection::GetServices() const noexcept + { + return pConnection.Get(); + } + std::unique_ptr WbemConnection::CreateListener_(WbemSink* pSink) { return std::make_unique(pSink, pConnection); } -} \ No newline at end of file +} diff --git a/IntelPresentMon/CommonUtilities/win/com/WbemConnection.h b/IntelPresentMon/CommonUtilities/win/com/WbemConnection.h index 7c2e589b..907a48cd 100644 --- a/IntelPresentMon/CommonUtilities/win/com/WbemConnection.h +++ b/IntelPresentMon/CommonUtilities/win/com/WbemConnection.h @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Intel Corporation +// Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: MIT #pragma once #include "ComPtr.h" @@ -16,6 +16,7 @@ namespace pmon::util::win::com { public: WbemConnection(); + IWbemServices* GetServices() const noexcept; template std::unique_ptr MakeListener(P&&...params) { @@ -30,4 +31,4 @@ namespace pmon::util::win::com ComManager com; Microsoft::WRL::ComPtr pConnection; }; -} \ No newline at end of file +} diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj b/IntelPresentMon/ControlLib/ControlLib.vcxproj index 189b880c..cc9d44a5 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj @@ -142,6 +142,7 @@ + @@ -167,6 +168,7 @@ + diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters index 07fd0667..9b5d4356 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters @@ -14,6 +14,9 @@ {b9383b96-c78b-4e0f-bd7a-bb9eace086ef} + + {a6df2cb9-9e2a-46e5-8adb-ff8f258e2a36} + @@ -93,6 +96,9 @@ + + Wmi + @@ -150,5 +156,8 @@ + + Wmi + diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp index a9778c51..1a469221 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp @@ -7,6 +7,7 @@ #include "igcl/IgclTelemetryProvider.h" #include "nvapi/NvapiTelemetryProvider.h" #include "nvml/NvmlTelemetryProvider.h" +#include "wmi/WmiTelemetryProvider.h" #include "../CommonUtilities/Exception.h" #include "../CommonUtilities/Qpc.h" #include "../Interprocess/source/Interprocess.h" @@ -267,6 +268,16 @@ namespace pmon::tel { providerPtrs_.clear(); + try { + providerPtrs_.push_back(std::make_shared()); + } + catch (const TelemetrySubsystemAbsent&) { + pmlog_warn(util::ReportException("WMI telemetry provider unavailable")); + } + catch (...) { + pmlog_error(util::ReportException("WMI telemetry provider construction failed")); + } + try { providerPtrs_.push_back(std::make_shared()); } diff --git a/IntelPresentMon/ControlLib/wmi/WmiTelemetryProvider.cpp b/IntelPresentMon/ControlLib/wmi/WmiTelemetryProvider.cpp new file mode 100644 index 00000000..53e3a923 --- /dev/null +++ b/IntelPresentMon/ControlLib/wmi/WmiTelemetryProvider.cpp @@ -0,0 +1,397 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#include "WmiTelemetryProvider.h" + +#include "../Exceptions.h" +#include "../Logging.h" +#include "../../CommonUtilities/Qpc.h" +#include "../../CommonUtilities/Exception.h" +#include "../../CommonUtilities/str/String.h" +#include "../../CommonUtilities/win/com/ComPtr.h" +#include "../../CommonUtilities/win/com/Comdef.h" +#include "../../CommonUtilities/win/com/WbemConnection.h" + +#include + +#include +#include +#include + +using namespace pmon; +using namespace util; + +namespace pmon::tel::wmi +{ + namespace + { + constexpr wchar_t kCpuIdentityQuery_[] = L"SELECT Name, Manufacturer FROM Win32_Processor"; + constexpr wchar_t kProcessorFrequencyCounter_[] = + L"\\Processor Information(_Total)\\Processor Frequency"; + constexpr wchar_t kProcessorPerformanceCounter_[] = + L"\\Processor Information(_Total)\\% Processor Performance"; + constexpr wchar_t kProcessorIdleTimeCounter_[] = + L"\\Processor(_Total)\\% Idle Time"; + + std::string ReadWmiStringProperty_(IWbemClassObject& object, const wchar_t* propertyName) + { + VARIANT variant{}; + VariantInit(&variant); + + const auto result = object.Get(propertyName, 0, &variant, nullptr, nullptr); + if (FAILED(result)) { + pmlog_warn("IWbemClassObject::Get failed").hr(result) + .pmwatch(str::ToNarrow(std::wstring{ propertyName })); + VariantClear(&variant); + return {}; + } + + std::string value{}; + if (variant.vt == VT_BSTR && variant.bstrVal != nullptr) { + value = str::TrimWhitespace( + str::ToNarrow(std::wstring{ variant.bstrVal, SysStringLen(variant.bstrVal) })); + } + else if (variant.vt != VT_NULL && variant.vt != VT_EMPTY) { + pmlog_warn("Unexpected VARIANT type for WMI string property") + .pmwatch(str::ToNarrow(std::wstring{ propertyName })) + .pmwatch((int)variant.vt); + } + + VariantClear(&variant); + return value; + } + + PM_DEVICE_VENDOR ResolveCpuVendor_(std::string_view manufacturer, std::string_view cpuName) + { + const auto matchVendor = [](std::string_view value) { + const auto lowerValue = str::ToLower(std::string{ value }); + if (lowerValue.contains("intel")) { + return PM_DEVICE_VENDOR_INTEL; + } + if (lowerValue.contains("amd")) { + return PM_DEVICE_VENDOR_AMD; + } + return PM_DEVICE_VENDOR_UNKNOWN; + }; + + const auto manufacturerVendor = matchVendor(manufacturer); + if (manufacturerVendor != PM_DEVICE_VENDOR_UNKNOWN) { + return manufacturerVendor; + } + + return matchVendor(cpuName); + } + } + + void WmiTelemetryProvider::QueryDeleter_::operator()(PDH_HQUERY query) const noexcept + { + if (query != nullptr) { + PdhCloseQuery(query); + } + } + + WmiTelemetryProvider::WmiTelemetryProvider() + { + const auto providerDeviceId = nextProviderDeviceId_; + const auto emplaceResult = devicesById_.try_emplace(providerDeviceId); + if (!emplaceResult.second) { + throw Except<>("Duplicate WMI provider device id encountered"); + } + + auto& device = emplaceResult.first->second; + device.providerDeviceId = providerDeviceId; + device.fingerprint.deviceType = PM_DEVICE_TYPE_SYSTEM; + device.fingerprint.vendor = PM_DEVICE_VENDOR_UNKNOWN; + device.fingerprint.deviceName = "UNKNOWN_CPU"; + + InitializeDevice_(device); + device.caps = BuildCapsForDevice_(device); + ++nextProviderDeviceId_; + } + + ProviderCapabilityMap WmiTelemetryProvider::GetCaps() + { + ProviderCapabilityMap capsByDeviceId{}; + for (const auto& entry : devicesById_) { + capsByDeviceId.emplace(entry.first, entry.second.caps); + } + return capsByDeviceId; + } + + const TelemetryDeviceFingerprint& WmiTelemetryProvider::GetFingerPrint( + ProviderDeviceId providerDeviceId) const + { + const auto iDevice = devicesById_.find(providerDeviceId); + if (iDevice == devicesById_.end()) { + throw Except<>("WMI provider device not found"); + } + return iDevice->second.fingerprint; + } + + TelemetryMetricValue WmiTelemetryProvider::PollMetric( + ProviderDeviceId providerDeviceId, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) + { + const auto iDevice = devicesById_.find(providerDeviceId); + if (iDevice == devicesById_.end()) { + throw Except<>("WMI provider device not found"); + } + + auto& device = iDevice->second; + + switch (metricId) { + case PM_METRIC_CPU_VENDOR: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return (int)device.fingerprint.vendor; + case PM_METRIC_CPU_NAME: + throw Except<>("PM_METRIC_CPU_NAME is static-only and is not served by poll path"); + case PM_METRIC_CPU_FREQUENCY: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto* pSample = PollCounterSampleEndpoint_(device, requestQpc); + if (pSample == nullptr || !pSample->hasFrequency) { + return 0.0; + } + return pSample->frequencyMhz; + } + case PM_METRIC_CPU_UTILIZATION: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto* pSample = PollCounterSampleEndpoint_(device, requestQpc); + if (pSample == nullptr || !pSample->hasUtilization) { + return 0.0; + } + return pSample->utilizationPercent; + } + default: + throw Except<>("Unsupported metric for WMI provider"); + } + } + + void WmiTelemetryProvider::ValidateScalarMetricIndex_(PM_METRIC metricId, uint32_t arrayIndex) + { + if (arrayIndex != 0) { + throw Except<>("WMI scalar metric queried with nonzero array index"); + } + (void)metricId; + } + + void WmiTelemetryProvider::InitializeDevice_(DeviceState_& device) const + { + PopulateFingerprintFromWmi_(device); + + PDH_HQUERY tempQuery = nullptr; + const auto openResult = PdhOpenQueryW(nullptr, 0, &tempQuery); + if (openResult != ERROR_SUCCESS) { + pmlog_error("PdhOpenQueryW failed").code(openResult); + throw Except("Unable to initialize WMI telemetry provider"); + } + device.query.reset(tempQuery); + + const auto addCounter = [&](const wchar_t* path, HCOUNTER& counter, const char* label) { + const auto addResult = PdhAddEnglishCounterW(device.query.get(), path, 0, &counter); + if (addResult != ERROR_SUCCESS) { + pmlog_warn(label).code(addResult) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + counter = nullptr; + } + }; + + addCounter( + kProcessorFrequencyCounter_, + device.processorFrequencyCounter, + "PdhAddEnglishCounterW failed for processor frequency"); + addCounter( + kProcessorPerformanceCounter_, + device.processorPerformanceCounter, + "PdhAddEnglishCounterW failed for processor performance"); + addCounter( + kProcessorIdleTimeCounter_, + device.processorIdleTimeCounter, + "PdhAddEnglishCounterW failed for processor idle time"); + + const auto collectResult = PdhCollectQueryData(device.query.get()); + if (collectResult != ERROR_SUCCESS) { + pmlog_error("PdhCollectQueryData initial collect failed").code(collectResult) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + throw Except("Unable to initialize WMI telemetry provider"); + } + + device.qpcFrequency = GetTimestampFrequencyUint64(); + device.nextSampleQpc = GetCurrentTimestamp(); + if (device.qpcFrequency != 0) { + device.nextSampleQpc += (int64_t)device.qpcFrequency; + } + } + + void WmiTelemetryProvider::PopulateFingerprintFromWmi_(DeviceState_& device) const + { + try { + win::com::WbemConnection connection; + auto* pServices = connection.GetServices(); + if (pServices == nullptr) { + pmlog_warn("WMI services connection was null") + .pmwatch(device.providerDeviceId); + return; + } + + win::com::ComPtr pEnumerator; + const auto queryResult = pServices->ExecQuery( + bstr_t(L"WQL"), + bstr_t(kCpuIdentityQuery_), + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + nullptr, + pEnumerator.ReleaseAndGetAddressOf()); + if (FAILED(queryResult)) { + pmlog_warn("IWbemServices::ExecQuery failed").hr(queryResult) + .pmwatch(device.providerDeviceId); + return; + } + + DWORD returned = 0; + win::com::ComPtr pClassObject; + const auto nextResult = pEnumerator->Next( + WBEM_INFINITE, + 1, + pClassObject.ReleaseAndGetAddressOf(), + &returned); + if (FAILED(nextResult) || returned == 0) { + pmlog_warn("IEnumWbemClassObject::Next failed").hr(nextResult) + .pmwatch(device.providerDeviceId) + .pmwatch(returned); + return; + } + + if (const auto cpuName = ReadWmiStringProperty_(*pClassObject.Get(), L"Name"); + !cpuName.empty()) { + device.fingerprint.deviceName = cpuName; + } + else { + pmlog_warn("WMI CPU name query returned empty result") + .pmwatch(device.providerDeviceId); + } + + const auto manufacturer = ReadWmiStringProperty_(*pClassObject.Get(), L"Manufacturer"); + device.fingerprint.vendor = ResolveCpuVendor_(manufacturer, device.fingerprint.deviceName); + if (device.fingerprint.vendor == PM_DEVICE_VENDOR_UNKNOWN) { + pmlog_warn("Unable to resolve CPU vendor from WMI") + .pmwatch(device.providerDeviceId) + .pmwatch(manufacturer) + .pmwatch(device.fingerprint.deviceName); + } + } + catch (...) { + pmlog_warn(util::ReportException("WMI CPU identity query failed")) + .pmwatch(device.providerDeviceId); + } + } + + ipc::MetricCapabilities WmiTelemetryProvider::BuildCapsForDevice_(DeviceState_& device) const + { + ipc::MetricCapabilities caps{}; + + caps.Set(PM_METRIC_CPU_VENDOR, 1); + caps.Set(PM_METRIC_CPU_NAME, 1); + + const auto* pSample = PollCounterSampleEndpoint_(device, 0); + if (pSample != nullptr && pSample->hasFrequency) { + caps.Set(PM_METRIC_CPU_FREQUENCY, 1); + } + if (pSample != nullptr && pSample->hasUtilization) { + caps.Set(PM_METRIC_CPU_UTILIZATION, 1); + } + + return caps; + } + + const WmiTelemetryProvider::CounterSample_* WmiTelemetryProvider::PollCounterSampleEndpoint_( + DeviceState_& device, + int64_t requestQpc) const + { + auto& cache = device.counterSampleEndpointCache; + if (requestQpc != 0 && cache.Matches(requestQpc)) { + return &cache.output; + } + + cache.output = {}; + cache.requestQpc = requestQpc; + + const auto sampleQpc = requestQpc != 0 ? requestQpc : GetCurrentTimestamp(); + if (device.query && + (device.nextSampleQpc == 0 || sampleQpc >= device.nextSampleQpc)) { + const auto collectResult = PdhCollectQueryData(device.query.get()); + if (collectResult != ERROR_SUCCESS) { + pmlog_warn("PdhCollectQueryData failed").code(collectResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + } + else if (device.qpcFrequency != 0) { + device.nextSampleQpc = sampleQpc + (int64_t)device.qpcFrequency; + } + else { + device.nextSampleQpc = sampleQpc; + } + } + + double value = 0.0; + if (TryReadCounterValue_( + device.processorFrequencyCounter, + "PdhGetFormattedCounterValue failed for processor frequency", + device, + value)) { + double performancePercent = 0.0; + if (TryReadCounterValue_( + device.processorPerformanceCounter, + "PdhGetFormattedCounterValue failed for processor performance", + device, + performancePercent)) { + cache.output.frequencyMhz = value * (performancePercent / 100.0); + cache.output.hasFrequency = true; + } + } + + if (TryReadCounterValue_( + device.processorIdleTimeCounter, + "PdhGetFormattedCounterValue failed for processor idle time", + device, + value)) { + cache.output.utilizationPercent = 100.0 - value; + cache.output.hasUtilization = true; + } + + return &cache.output; + } + + bool WmiTelemetryProvider::TryReadCounterValue_( + HCOUNTER counter, + const char* label, + const DeviceState_& device, + double& value) + { + if (counter == nullptr) { + value = 0.0; + return false; + } + + PDH_FMT_COUNTERVALUE counterValue{}; + DWORD counterType = 0; + const auto result = PdhGetFormattedCounterValue( + counter, + PDH_FMT_DOUBLE, + &counterType, + &counterValue); + if (result != ERROR_SUCCESS) { + pmlog_warn(label).code(result).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + value = 0.0; + return false; + } + + value = counterValue.doubleValue; + return true; + } +} diff --git a/IntelPresentMon/ControlLib/wmi/WmiTelemetryProvider.h b/IntelPresentMon/ControlLib/wmi/WmiTelemetryProvider.h new file mode 100644 index 00000000..c6ba163b --- /dev/null +++ b/IntelPresentMon/ControlLib/wmi/WmiTelemetryProvider.h @@ -0,0 +1,78 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#pragma once + +#include "../../CommonUtilities/win/WinAPI.h" +#include "../EndpointCache.h" +#include "../TelemetryProvider.h" + +#include + +#include +#include +#include +#include + +namespace pmon::tel::wmi +{ + class WmiTelemetryProvider : public TelemetryProvider + { + public: + WmiTelemetryProvider(); + ~WmiTelemetryProvider() override = default; + ProviderCapabilityMap GetCaps() override; + const TelemetryDeviceFingerprint& GetFingerPrint(ProviderDeviceId providerDeviceId) const override; + TelemetryMetricValue PollMetric( + ProviderDeviceId providerDeviceId, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) override; + + private: + struct QueryDeleter_ + { + void operator()(PDH_HQUERY query) const noexcept; + }; + + struct CounterSample_ + { + double frequencyMhz = 0.0; + double utilizationPercent = 0.0; + bool hasFrequency = false; + bool hasUtilization = false; + }; + + struct DeviceState_ + { + ProviderDeviceId providerDeviceId = 0; + TelemetryDeviceFingerprint fingerprint{}; + ipc::MetricCapabilities caps{}; + + std::unique_ptr, QueryDeleter_> query{}; + HCOUNTER processorFrequencyCounter = {}; + HCOUNTER processorPerformanceCounter = {}; + HCOUNTER processorIdleTimeCounter = {}; + uint64_t qpcFrequency = 0; + int64_t nextSampleQpc = 0; + + pmon::tele::EndpointCache counterSampleEndpointCache{}; + }; + + static void ValidateScalarMetricIndex_(PM_METRIC metricId, uint32_t arrayIndex); + void InitializeDevice_(DeviceState_& device) const; + void PopulateFingerprintFromWmi_(DeviceState_& device) const; + ipc::MetricCapabilities BuildCapsForDevice_(DeviceState_& device) const; + const CounterSample_* PollCounterSampleEndpoint_( + DeviceState_& device, + int64_t requestQpc) const; + static bool TryReadCounterValue_( + HCOUNTER counter, + const char* label, + const DeviceState_& device, + double& value); + + private: + std::unordered_map devicesById_{}; + ProviderDeviceId nextProviderDeviceId_ = 1; + }; +} From 51be9690809d4b90bc7967dfbb56f276862488de Mon Sep 17 00:00:00 2001 From: Chili Date: Sat, 14 Mar 2026 16:31:07 +0900 Subject: [PATCH 09/42] construct providers --- .../ControlLib/TelemetryCoordinator.cpp | 61 +++++++------------ 1 file changed, 23 insertions(+), 38 deletions(-) diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp index 1a469221..dce17131 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp @@ -268,45 +268,30 @@ namespace pmon::tel { providerPtrs_.clear(); - try { - providerPtrs_.push_back(std::make_shared()); - } - catch (const TelemetrySubsystemAbsent&) { - pmlog_warn(util::ReportException("WMI telemetry provider unavailable")); - } - catch (...) { - pmlog_error(util::ReportException("WMI telemetry provider construction failed")); - } - - try { - providerPtrs_.push_back(std::make_shared()); - } - catch (const TelemetrySubsystemAbsent&) { - pmlog_warn(util::ReportException("IGCL telemetry provider unavailable")); - } - catch (...) { - pmlog_error(util::ReportException("IGCL telemetry provider construction failed")); - } - - try { - providerPtrs_.push_back(std::make_shared()); - } - catch (const TelemetrySubsystemAbsent&) { - pmlog_warn(util::ReportException("NVAPI telemetry provider unavailable")); - } - catch (...) { - pmlog_error(util::ReportException("NVAPI telemetry provider construction failed")); - } + const auto tryAddProvider = [this](const char* missingMessage, const char* failureMessage) { + try { + providerPtrs_.push_back(std::make_shared()); + } + catch (const TelemetrySubsystemAbsent&) { + pmlog_dbg(util::ReportException(missingMessage)); + } + catch (...) { + pmlog_error(util::ReportException(failureMessage)); + } + }; - try { - providerPtrs_.push_back(std::make_shared()); - } - catch (const TelemetrySubsystemAbsent&) { - pmlog_warn(util::ReportException("NVML telemetry provider unavailable")); - } - catch (...) { - pmlog_error(util::ReportException("NVML telemetry provider construction failed")); - } + tryAddProvider.operator()( + "WMI telemetry provider unavailable", + "WMI telemetry provider construction failed"); + tryAddProvider.operator()( + "IGCL telemetry provider unavailable", + "IGCL telemetry provider construction failed"); + tryAddProvider.operator()( + "NVAPI telemetry provider unavailable", + "NVAPI telemetry provider construction failed"); + tryAddProvider.operator()( + "NVML telemetry provider unavailable", + "NVML telemetry provider construction failed"); } void TelemetryCoordinator::BuildLogicalDevicesAndRoutes_() From 6446a7ff6a5a07872ba89bd08f6e86c97b089c5d Mon Sep 17 00:00:00 2001 From: Chili Date: Sun, 15 Mar 2026 07:43:43 +0900 Subject: [PATCH 10/42] switchover success w/ cpu+gpu thread merger --- IntelPresentMon/ControlLib/ControlLib.vcxproj | 1 + .../ControlLib/ControlLib.vcxproj.filters | 1 + IntelPresentMon/ControlLib/MetricUse.h | 56 ++ .../ControlLib/TelemetryCoordinator.cpp | 326 +++++++---- .../ControlLib/TelemetryCoordinator.h | 10 +- .../ControlLib/igcl/IgclTelemetryProvider.cpp | 11 +- .../nvapi/NvapiTelemetryProvider.cpp | 10 +- .../ControlLib/nvml/NvmlTelemetryProvider.cpp | 6 +- .../ControlLib/wmi/WmiTelemetryProvider.cpp | 10 +- IntelPresentMon/PresentMonService/MetricUse.h | 53 +- .../PresentMonService/PMMainThread.cpp | 553 ++---------------- 11 files changed, 344 insertions(+), 693 deletions(-) create mode 100644 IntelPresentMon/ControlLib/MetricUse.h diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj b/IntelPresentMon/ControlLib/ControlLib.vcxproj index cc9d44a5..ccaaf046 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj @@ -120,6 +120,7 @@ + diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters index 9b5d4356..acbc31bb 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters @@ -79,6 +79,7 @@ + diff --git a/IntelPresentMon/ControlLib/MetricUse.h b/IntelPresentMon/ControlLib/MetricUse.h new file mode 100644 index 00000000..39ea77c5 --- /dev/null +++ b/IntelPresentMon/ControlLib/MetricUse.h @@ -0,0 +1,56 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#pragma once + +#include "../CommonUtilities/Hash.h" +#include "../PresentMonAPI2/PresentMonAPI.h" +#include +#include +#include +#include +#include + +namespace pmon::svc +{ + struct MetricUse + { + PM_METRIC metricId; + uint32_t deviceId; + uint32_t arrayIdx; + + template + void serialize(A& ar) + { + ar(CEREAL_NVP(metricId), + CEREAL_NVP(deviceId), + CEREAL_NVP(arrayIdx)); + } + + bool operator==(const MetricUse& rhs) const + { + return metricId == rhs.metricId && + deviceId == rhs.deviceId && + arrayIdx == rhs.arrayIdx; + } + }; + + using DeviceMetricUse = std::unordered_map>; +} + +namespace std +{ + template<> + struct hash + { + size_t operator()(const pmon::svc::MetricUse& mu) const noexcept + { + const uint64_t devIdx = + (uint64_t(mu.deviceId) << 32) | uint64_t(mu.arrayIdx); + + using Under = std::underlying_type_t; + const Under mid = (Under)mu.metricId; + + return pmon::util::hash::DualHash(mid, devIdx); + } + }; +} diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp index dce17131..6d28f2b7 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp @@ -12,9 +12,11 @@ #include "../CommonUtilities/Qpc.h" #include "../Interprocess/source/Interprocess.h" #include "../Interprocess/source/SystemDeviceId.h" +#include "../Interprocess/source/metadata/MetricList.h" #include #include #include +#include #include #include #include @@ -29,6 +31,17 @@ namespace pmon::tel uint32_t arraySize = 0; uint32_t providerCoverageScore = 0; }; + + bool IsStaticMetric_(PM_METRIC metricId) noexcept + { + switch (metricId) { +#define X_(id_, type_, ...) case id_: return type_ == PM_METRIC_TYPE_STATIC; + METRIC_LIST(X_) +#undef X_ + default: + return false; + } + } } TelemetryCoordinator::TelemetryCoordinator() @@ -37,33 +50,57 @@ namespace pmon::tel BuildLogicalDevicesAndRoutes_(); } - void TelemetryCoordinator::PopulateStaticsToIpc(ipc::ServiceComms& comms) const + void TelemetryCoordinator::RegisterDevicesToIpc(ipc::ServiceComms& comms) const { - const auto requestQpc = util::GetCurrentTimestamp(); - // TODO: make static population dynamic by metric id and metadata instead of hardcoded checks. + bool cpuRegistered = false; + for (const auto& [logicalDeviceId, logicalDevice] : logicalDevicesById_) { - TelemetryDeviceFingerprint providerFingerprint{}; - bool haveProviderFingerprint = false; - for (const auto& providerDevice : logicalDevice.providerDevices) { - const auto pProvider = providerDevice.pProvider.lock(); - if (!pProvider) { - pmlog_warn("Expired provider while resolving provider-device fingerprint for statics") - .pmwatch(logicalDevice.logicalDeviceId) - .pmwatch(providerDevice.providerDeviceId); - continue; - } + bool haveFingerprint = false; + auto fingerprint = ResolveLogicalDeviceFingerprint_(logicalDevice, haveFingerprint); + auto caps = BuildRoutedCapabilities_(logicalDevice); - try { - providerFingerprint = pProvider->GetFingerPrint(providerDevice.providerDeviceId); - haveProviderFingerprint = true; - break; + const auto vendor = haveFingerprint ? fingerprint.vendor : PM_DEVICE_VENDOR_UNKNOWN; + const auto name = haveFingerprint && !fingerprint.deviceName.empty() ? + fingerprint.deviceName : std::string{ "UNKNOWN_CPU" }; + + try { + if (logicalDeviceId != ipc::kSystemDeviceId) { + comms.RegisterGpuDevice( + logicalDeviceId, + vendor, + haveFingerprint && !fingerprint.deviceName.empty() ? + fingerprint.deviceName : std::string{ "UNKNOWN_GPU" }, + caps, + std::span{}); } - catch (...) { - pmlog_error(util::ReportException("Provider-device fingerprint query failed for statics")) - .pmwatch(logicalDevice.logicalDeviceId) - .pmwatch(providerDevice.providerDeviceId); + else { + comms.RegisterCpuDevice(vendor, name, caps); + cpuRegistered = true; } } + catch (...) { + pmlog_error(util::ReportException("RegisterDevicesToIpc failed for logical device")) + .pmwatch(logicalDeviceId) + .pmwatch((int)vendor) + .pmwatch(haveFingerprint) + .pmwatch(fingerprint.deviceName); + } + } + + if (!cpuRegistered) { + comms.RegisterCpuDevice(PM_DEVICE_VENDOR_UNKNOWN, "UNKNOWN_CPU", {}); + } + comms.FinalizeGpuDevices(); + } + + void TelemetryCoordinator::PopulateStaticsToIpc(ipc::ServiceComms& comms) const + { + const auto requestQpc = util::GetCurrentTimestamp(); + // TODO: make static population dynamic by metric id and metadata instead of hardcoded checks. + for (const auto& [logicalDeviceId, logicalDevice] : logicalDevicesById_) { + bool haveProviderFingerprint = false; + const auto providerFingerprint = + ResolveLogicalDeviceFingerprint_(logicalDevice, haveProviderFingerprint); try { if (logicalDeviceId != ipc::kSystemDeviceId) { @@ -142,68 +179,13 @@ namespace pmon::tel { ipc::MetricCapabilities availability; - for (const auto& [logicalDeviceId, logicalDevice] : logicalDevicesById_) { - for (const auto& [metricId, providerDeviceIndex] : logicalDevice.routes) { - if (providerDeviceIndex >= logicalDevice.providerDevices.size()) { - pmlog_error("Route points outside provider device list in GetAvailability") - .pmwatch(logicalDeviceId) - .pmwatch((int)metricId) - .pmwatch(providerDeviceIndex) - .pmwatch(logicalDevice.providerDevices.size()); - continue; - } - - const auto& providerDevice = logicalDevice.providerDevices[providerDeviceIndex]; - const auto pProvider = providerDevice.pProvider.lock(); - if (!pProvider) { - pmlog_error("Route provider expired in GetAvailability") - .pmwatch(logicalDeviceId) - .pmwatch((int)metricId) - .pmwatch(providerDevice.providerDeviceId); - continue; - } - - TelemetryDeviceFingerprint providerFingerprint{}; - bool haveProviderFingerprint = false; - try { - providerFingerprint = pProvider->GetFingerPrint(providerDevice.providerDeviceId); - haveProviderFingerprint = true; - const auto capabilityMap = pProvider->GetCaps(); - const auto itDeviceCaps = capabilityMap.find(providerDevice.providerDeviceId); - if (itDeviceCaps == capabilityMap.end()) { - pmlog_error("Provider did not return caps for routed device in GetAvailability") - .pmwatch(logicalDeviceId) - .pmwatch((int)providerFingerprint.vendor) - .pmwatch(providerFingerprint.deviceName) - .pmwatch(providerDevice.providerDeviceId) - .pmwatch((int)metricId); - continue; - } - - const auto arraySize = itDeviceCaps->second.Check(metricId); - if (arraySize == 0) { - pmlog_error("Provider caps missing routed metric in GetAvailability") - .pmwatch(logicalDeviceId) - .pmwatch((int)providerFingerprint.vendor) - .pmwatch(providerFingerprint.deviceName) - .pmwatch(providerDevice.providerDeviceId) - .pmwatch((int)metricId); - continue; - } - - const auto existingSize = availability.Check(metricId); - if (arraySize > existingSize) { - availability.Set(metricId, arraySize); - } - } - catch (...) { - pmlog_error(util::ReportException("GetAvailability provider query failed")) - .pmwatch(logicalDeviceId) - .pmwatch((int)providerFingerprint.vendor) - .pmwatch(providerFingerprint.deviceName) - .pmwatch(haveProviderFingerprint) - .pmwatch(providerDevice.providerDeviceId) - .pmwatch((int)metricId); + for (const auto& entry : logicalDevicesById_) { + const auto& logicalDevice = entry.second; + const auto routedCaps = BuildRoutedCapabilities_(logicalDevice); + for (const auto& [metricId, arraySize] : routedCaps) { + const auto existingSize = availability.Check(metricId); + if (arraySize > existingSize) { + availability.Set(metricId, arraySize); } } } @@ -212,52 +194,67 @@ namespace pmon::tel } size_t TelemetryCoordinator::PollToIpc( - const std::span& metricUse, + const svc::DeviceMetricUse& metricUse, ipc::ServiceComms& comms) const { const auto requestQpc = util::GetCurrentTimestamp(); size_t samplesWritten = 0; - for (const auto& use : metricUse) { - if (use.metric >= PM_METRIC_COUNT_) { - pmlog_warn("Invalid metric id in PollToIpc request") - .pmwatch((int)use.metric) - .pmwatch(use.deviceId) - .pmwatch(use.arrayIndex); + for (const auto& [deviceId, deviceMetricUse] : metricUse) { + if (deviceId == 0) { continue; } - const auto itLogical = logicalDevicesById_.find(use.deviceId); + const auto itLogical = logicalDevicesById_.find(deviceId); if (itLogical == logicalDevicesById_.end()) { pmlog_warn("Unknown logical device id in PollToIpc request") - .pmwatch(use.deviceId) - .pmwatch((int)use.metric) - .pmwatch(use.arrayIndex); + .pmwatch(deviceId); continue; } const auto& logicalDevice = itLogical->second; - try { - const auto value = PollMetricForRoute_( - logicalDevice, use.metric, use.arrayIndex, requestQpc); - const auto qpc = (uint64_t)util::GetCurrentTimestamp(); - - if (logicalDevice.logicalDeviceId != ipc::kSystemDeviceId) { - auto& store = comms.GetGpuDataStore(logicalDevice.logicalDeviceId); - PushValueToTelemetryMap_(store.telemetryData, use.metric, use.arrayIndex, value, qpc); + for (const auto& use : deviceMetricUse) { + if (use.deviceId != deviceId) { + pmlog_warn("Metric use device id did not match owning device bucket") + .pmwatch(deviceId) + .pmwatch(use.deviceId) + .pmwatch((int)use.metricId) + .pmwatch(use.arrayIdx); + continue; } - else { - auto& store = comms.GetSystemDataStore(); - PushValueToTelemetryMap_(store.telemetryData, use.metric, use.arrayIndex, value, qpc); + if (use.metricId >= PM_METRIC_COUNT_) { + pmlog_warn("Invalid metric id in PollToIpc request") + .pmwatch((int)use.metricId) + .pmwatch(deviceId) + .pmwatch(use.arrayIdx); + continue; + } + if (IsStaticMetric_(use.metricId)) { + continue; } - ++samplesWritten; - } - catch (...) { - pmlog_error(util::ReportException("PollToIpc failed while writing sample")) - .pmwatch(logicalDevice.logicalDeviceId) - .pmwatch((int)use.metric) - .pmwatch(use.arrayIndex); + try { + const auto value = PollMetricForRoute_( + logicalDevice, use.metricId, use.arrayIdx, requestQpc); + const auto qpc = (uint64_t)util::GetCurrentTimestamp(); + + if (logicalDevice.logicalDeviceId != ipc::kSystemDeviceId) { + auto& store = comms.GetGpuDataStore(logicalDevice.logicalDeviceId); + PushValueToTelemetryMap_(store.telemetryData, use.metricId, use.arrayIdx, value, qpc); + } + else { + auto& store = comms.GetSystemDataStore(); + PushValueToTelemetryMap_(store.telemetryData, use.metricId, use.arrayIdx, value, qpc); + } + + ++samplesWritten; + } + catch (...) { + pmlog_error(util::ReportException("PollToIpc failed while writing sample")) + .pmwatch(logicalDevice.logicalDeviceId) + .pmwatch((int)use.metricId) + .pmwatch(use.arrayIdx); + } } } @@ -468,6 +465,111 @@ namespace pmon::tel return itLogical->second; } + TelemetryDeviceFingerprint TelemetryCoordinator::ResolveLogicalDeviceFingerprint_( + const LogicalDevice_& logicalDevice, + bool& haveFingerprint) const + { + TelemetryDeviceFingerprint fingerprint{}; + haveFingerprint = false; + + for (const auto& providerDevice : logicalDevice.providerDevices) { + const auto pProvider = providerDevice.pProvider.lock(); + if (!pProvider) { + pmlog_warn("Expired provider while resolving logical-device fingerprint") + .pmwatch(logicalDevice.logicalDeviceId) + .pmwatch(providerDevice.providerDeviceId); + continue; + } + + try { + const auto providerFingerprint = pProvider->GetFingerPrint(providerDevice.providerDeviceId); + if (!haveFingerprint) { + fingerprint = providerFingerprint; + haveFingerprint = true; + } + else { + MergeTelemetryDeviceFingerprint(fingerprint, providerFingerprint); + } + } + catch (...) { + pmlog_error(util::ReportException("Logical-device fingerprint query failed")) + .pmwatch(logicalDevice.logicalDeviceId) + .pmwatch(providerDevice.providerDeviceId); + } + } + + return fingerprint; + } + + ipc::MetricCapabilities TelemetryCoordinator::BuildRoutedCapabilities_( + const LogicalDevice_& logicalDevice) const + { + ipc::MetricCapabilities caps{}; + + for (const auto& [metricId, providerDeviceIndex] : logicalDevice.routes) { + if (providerDeviceIndex >= logicalDevice.providerDevices.size()) { + pmlog_error("Route points outside provider device list in BuildRoutedCapabilities") + .pmwatch(logicalDevice.logicalDeviceId) + .pmwatch((int)metricId) + .pmwatch(providerDeviceIndex) + .pmwatch(logicalDevice.providerDevices.size()); + continue; + } + + const auto& providerDevice = logicalDevice.providerDevices[providerDeviceIndex]; + const auto pProvider = providerDevice.pProvider.lock(); + if (!pProvider) { + pmlog_error("Route provider expired in BuildRoutedCapabilities") + .pmwatch(logicalDevice.logicalDeviceId) + .pmwatch((int)metricId) + .pmwatch(providerDevice.providerDeviceId); + continue; + } + + TelemetryDeviceFingerprint providerFingerprint{}; + bool haveProviderFingerprint = false; + try { + providerFingerprint = pProvider->GetFingerPrint(providerDevice.providerDeviceId); + haveProviderFingerprint = true; + const auto capabilityMap = pProvider->GetCaps(); + const auto itDeviceCaps = capabilityMap.find(providerDevice.providerDeviceId); + if (itDeviceCaps == capabilityMap.end()) { + pmlog_error("Provider did not return caps for routed device") + .pmwatch(logicalDevice.logicalDeviceId) + .pmwatch((int)providerFingerprint.vendor) + .pmwatch(providerFingerprint.deviceName) + .pmwatch(providerDevice.providerDeviceId) + .pmwatch((int)metricId); + continue; + } + + const auto arraySize = itDeviceCaps->second.Check(metricId); + if (arraySize == 0) { + pmlog_error("Provider caps missing routed metric") + .pmwatch(logicalDevice.logicalDeviceId) + .pmwatch((int)providerFingerprint.vendor) + .pmwatch(providerFingerprint.deviceName) + .pmwatch(providerDevice.providerDeviceId) + .pmwatch((int)metricId); + continue; + } + + caps.Set(metricId, arraySize); + } + catch (...) { + pmlog_error(util::ReportException("BuildRoutedCapabilities provider query failed")) + .pmwatch(logicalDevice.logicalDeviceId) + .pmwatch((int)providerFingerprint.vendor) + .pmwatch(providerFingerprint.deviceName) + .pmwatch(haveProviderFingerprint) + .pmwatch(providerDevice.providerDeviceId) + .pmwatch((int)metricId); + } + } + + return caps; + } + void TelemetryCoordinator::PushValueToTelemetryMap_( ipc::TelemetryMap& telemetryMap, PM_METRIC metricId, diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.h b/IntelPresentMon/ControlLib/TelemetryCoordinator.h index e7da0bfc..5d384e64 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.h +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.h @@ -2,9 +2,9 @@ // SPDX-License-Identifier: MIT #pragma once +#include "MetricUse.h" #include "TelemetryProvider.h" #include -#include #include #include @@ -22,13 +22,15 @@ namespace pmon::tel // Constructs all known concrete providers, correlates logical devices, // and builds metric polling routes. TelemetryCoordinator(); + // Registers logical CPU/GPU devices and per-device routed capabilities with IPC. + void RegisterDevicesToIpc(ipc::ServiceComms& comms) const; // Populates available static data into IPC device stores. void PopulateStaticsToIpc(ipc::ServiceComms& comms) const; // Returns aggregate availability across all routed logical devices. ipc::MetricCapabilities GetAvailability() const; // Polls routed telemetry metrics and pushes samples directly to IPC rings. size_t PollToIpc( - const std::span& metricUse, + const svc::DeviceMetricUse& metricUse, ipc::ServiceComms& comms) const; private: @@ -49,6 +51,10 @@ namespace pmon::tel void TryCreateConcreteProviders_(); void BuildLogicalDevicesAndRoutes_(); LogicalDevice_& GetOrCreateLogicalDevice_(const TelemetryDeviceFingerprint& fingerprint); + TelemetryDeviceFingerprint ResolveLogicalDeviceFingerprint_( + const LogicalDevice_& logicalDevice, + bool& haveFingerprint) const; + ipc::MetricCapabilities BuildRoutedCapabilities_(const LogicalDevice_& logicalDevice) const; static void PushValueToTelemetryMap_( ipc::TelemetryMap& telemetryMap, PM_METRIC metricId, diff --git a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp index f86147f8..fe51e38e 100644 --- a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp @@ -4,6 +4,7 @@ #include "../Exceptions.h" #include "../Logging.h" +#include "../../CommonUtilities/Qpc.h" #include "../../CommonUtilities/ref/GeneratedReflection.h" #include @@ -24,13 +25,12 @@ namespace pmon::tel::igcl bool IgclTelemetryProvider::TelemetrySampleBuffer_::Matches(int64_t requestQpc) const noexcept { - return hasCurrent_ && requestQpc != 0 && requestQpcs_[currentIndex_] == requestQpc; + return hasCurrent_ && requestQpcs_[currentIndex_] == requestQpc; } ctl_power_telemetry_t& IgclTelemetryProvider::TelemetrySampleBuffer_::PrepareForWrite(int64_t requestQpc) noexcept { - if (requestQpc != 0 && hasCurrent_ && - requestQpcs_[currentIndex_] != 0 && requestQpcs_[currentIndex_] != requestQpc) { + if (hasCurrent_ && requestQpcs_[currentIndex_] != requestQpc) { previousIndex_ = currentIndex_; currentIndex_ = currentIndex_ == 0 ? 1u : 0u; hasPrevious_ = true; @@ -375,6 +375,7 @@ namespace pmon::tel::igcl ipc::MetricCapabilities IgclTelemetryProvider::BuildCapsForDevice_(DeviceState_& device) const { ipc::MetricCapabilities caps{}; + const auto requestQpc = GetCurrentTimestamp(); // Static capabilities can exist even if they do not route through dynamic polling. caps.Set(PM_METRIC_GPU_VENDOR, 1); @@ -385,7 +386,7 @@ namespace pmon::tel::igcl caps.Set(PM_METRIC_GPU_SUSTAINED_POWER_LIMIT, 1); } - const auto* pMemoryState = PollMemoryStateEndpoint_(device, 0); + const auto* pMemoryState = PollMemoryStateEndpoint_(device, requestQpc); if (pMemoryState != nullptr) { caps.Set(PM_METRIC_GPU_MEM_SIZE, 1); caps.Set(PM_METRIC_GPU_MEM_USED, 1); @@ -398,7 +399,7 @@ namespace pmon::tel::igcl device.gpuMemMaxBwCacheValueBps = memoryBandwidth->maxBandwidth; } - const auto& sample = PollTelemetryEndpoint_(device, 0); + const auto& sample = PollTelemetryEndpoint_(device, requestQpc); if (IsUsageTelemetryItemSupported_(sample.gpuEnergyCounter)) { caps.Set(PM_METRIC_GPU_POWER, 1); diff --git a/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.cpp b/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.cpp index 83d76ecd..0fed9c71 100644 --- a/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.cpp @@ -4,6 +4,7 @@ #include "../Exceptions.h" #include "../Logging.h" +#include "../../CommonUtilities/Qpc.h" #include #include @@ -168,13 +169,14 @@ namespace pmon::tel::nvapi ipc::MetricCapabilities NvapiTelemetryProvider::BuildCapsForDevice_(DeviceState_& device) const { ipc::MetricCapabilities caps{}; + const auto requestQpc = GetCurrentTimestamp(); caps.Set(PM_METRIC_GPU_VENDOR, 1); caps.Set(PM_METRIC_GPU_NAME, 1); double value = 0.0; - if (const auto* pThermals = PollThermalEndpoint_(device, 0)) { + if (const auto* pThermals = PollThermalEndpoint_(device, requestQpc)) { if (TryGetThermalValue_(*pThermals, NVAPI_THERMAL_TARGET_GPU, true, value)) { caps.Set(PM_METRIC_GPU_TEMPERATURE, 1); } @@ -183,7 +185,7 @@ namespace pmon::tel::nvapi } } - if (const auto* pClocks = PollClockEndpoint_(device, 0)) { + if (const auto* pClocks = PollClockEndpoint_(device, requestQpc)) { if (TryGetClockValue_(*pClocks, NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS, value)) { caps.Set(PM_METRIC_GPU_FREQUENCY, 1); } @@ -192,7 +194,7 @@ namespace pmon::tel::nvapi } } - if (const auto* pUtilization = PollUtilizationEndpoint_(device, 0)) { + if (const auto* pUtilization = PollUtilizationEndpoint_(device, requestQpc)) { if (TryGetUtilizationValue_( *pUtilization, pwr::nv::NVAPI_GPU_UTILIZATION_DOMAIN_GPU, value)) { caps.Set(PM_METRIC_GPU_UTILIZATION, 1); @@ -203,7 +205,7 @@ namespace pmon::tel::nvapi } } - if (PollTachEndpoint_(device, 0) != nullptr) { + if (PollTachEndpoint_(device, requestQpc) != nullptr) { caps.Set(PM_METRIC_GPU_FAN_SPEED, 1); } diff --git a/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.cpp b/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.cpp index 64b5d9cf..98facb7d 100644 --- a/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.cpp @@ -4,6 +4,7 @@ #include "../Exceptions.h" #include "../Logging.h" +#include "../../CommonUtilities/Qpc.h" #include @@ -208,6 +209,7 @@ namespace pmon::tel::nvml ipc::MetricCapabilities NvmlTelemetryProvider::BuildCapsForDevice_(DeviceState_& device) const { ipc::MetricCapabilities caps{}; + const auto requestQpc = GetCurrentTimestamp(); caps.Set(PM_METRIC_GPU_VENDOR, 1); caps.Set(PM_METRIC_GPU_NAME, 1); @@ -220,7 +222,7 @@ namespace pmon::tel::nvml caps.Set(PM_METRIC_GPU_SUSTAINED_POWER_LIMIT, 1); } - if (const auto* pMemoryInfo = PollMemoryInfoEndpoint_(device, 0)) { + if (const auto* pMemoryInfo = PollMemoryInfoEndpoint_(device, requestQpc)) { const auto totalBytes = GetLegacyTotalMemoryBytes_(*pMemoryInfo); if (totalBytes != 0) { caps.Set(PM_METRIC_GPU_MEM_SIZE, 1); @@ -237,7 +239,7 @@ namespace pmon::tel::nvml int64_t requestQpc) const { auto& cache = device.memoryInfoEndpointCache; - if (requestQpc != 0 && cache.Matches(requestQpc)) { + if (cache.Matches(requestQpc)) { return cache.output ? &*cache.output : nullptr; } diff --git a/IntelPresentMon/ControlLib/wmi/WmiTelemetryProvider.cpp b/IntelPresentMon/ControlLib/wmi/WmiTelemetryProvider.cpp index 53e3a923..28f0ff1d 100644 --- a/IntelPresentMon/ControlLib/wmi/WmiTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/wmi/WmiTelemetryProvider.cpp @@ -221,10 +221,9 @@ namespace pmon::tel::wmi } device.qpcFrequency = GetTimestampFrequencyUint64(); + // Seed the gate to "now" so the first post-init probe performs the + // second PDH collection needed for formatted CPU counters. device.nextSampleQpc = GetCurrentTimestamp(); - if (device.qpcFrequency != 0) { - device.nextSampleQpc += (int64_t)device.qpcFrequency; - } } void WmiTelemetryProvider::PopulateFingerprintFromWmi_(DeviceState_& device) const @@ -292,11 +291,12 @@ namespace pmon::tel::wmi ipc::MetricCapabilities WmiTelemetryProvider::BuildCapsForDevice_(DeviceState_& device) const { ipc::MetricCapabilities caps{}; + const auto requestQpc = GetCurrentTimestamp(); caps.Set(PM_METRIC_CPU_VENDOR, 1); caps.Set(PM_METRIC_CPU_NAME, 1); - const auto* pSample = PollCounterSampleEndpoint_(device, 0); + const auto* pSample = PollCounterSampleEndpoint_(device, requestQpc); if (pSample != nullptr && pSample->hasFrequency) { caps.Set(PM_METRIC_CPU_FREQUENCY, 1); } @@ -312,7 +312,7 @@ namespace pmon::tel::wmi int64_t requestQpc) const { auto& cache = device.counterSampleEndpointCache; - if (requestQpc != 0 && cache.Matches(requestQpc)) { + if (cache.Matches(requestQpc)) { return &cache.output; } diff --git a/IntelPresentMon/PresentMonService/MetricUse.h b/IntelPresentMon/PresentMonService/MetricUse.h index ac4ef4b0..c004c07b 100644 --- a/IntelPresentMon/PresentMonService/MetricUse.h +++ b/IntelPresentMon/PresentMonService/MetricUse.h @@ -1,54 +1,3 @@ #pragma once -#include "../CommonUtilities/Hash.h" -#include -#include -#include -#include -#include -namespace pmon::svc -{ - struct MetricUse - { - PM_METRIC metricId; - uint32_t deviceId; - uint32_t arrayIdx; - - template - void serialize(A& ar) - { - ar(CEREAL_NVP(metricId), - CEREAL_NVP(deviceId), - CEREAL_NVP(arrayIdx)); - } - - bool operator==(const MetricUse& rhs) const - { - return metricId == rhs.metricId && - deviceId == rhs.deviceId && - arrayIdx == rhs.arrayIdx; - } - }; - - using DeviceMetricUse = std::unordered_map>; -} - -// Must be visible before any std::unordered_set instantiation -namespace std -{ - template<> - struct hash - { - size_t operator()(const pmon::svc::MetricUse& mu) const noexcept - { - const uint64_t devIdx = - (uint64_t(mu.deviceId) << 32) | uint64_t(mu.arrayIdx); - - // Avoid depending on std::hash existing: - using Under = std::underlying_type_t; - const Under mid = (Under)mu.metricId; - - return pmon::util::hash::DualHash(mid, devIdx); - } - }; -} +#include "../ControlLib/MetricUse.h" diff --git a/IntelPresentMon/PresentMonService/PMMainThread.cpp b/IntelPresentMon/PresentMonService/PMMainThread.cpp index cd39b8b8..55229c1f 100644 --- a/IntelPresentMon/PresentMonService/PMMainThread.cpp +++ b/IntelPresentMon/PresentMonService/PMMainThread.cpp @@ -1,17 +1,12 @@ -// Copyright (C) 2022 Intel Corporation +// Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: MIT #include "Logging.h" #include "Service.h" #include "ActionServer.h" #include "PresentMon.h" -#include "PowerTelemetryContainer.h" #include "FrameBroadcaster.h" -#include "..\ControlLib\WmiCpu.h" -#include +#include "..\ControlLib\TelemetryCoordinator.h" #include "../Interprocess/source/Interprocess.h" -#include "../Interprocess/source/ShmNamer.h" -#include "../Interprocess/source/MetricCapabilitiesShim.h" -#include "../Interprocess/source/SystemDeviceId.h" #include "CliOptions.h" #include "Registry.h" #include "GlobalIdentifiers.h" @@ -19,7 +14,6 @@ #include #include #include "../CommonUtilities/IntervalWaiter.h" -#include "../CommonUtilities/PrecisionWaiter.h" #include "../CommonUtilities/win/Event.h" #include "../CommonUtilities/log/IdentificationTable.h" @@ -32,7 +26,6 @@ using namespace pmon; using namespace svc; using namespace util; using v = log::V; -namespace vi = std::views; namespace @@ -115,458 +108,59 @@ void EventFlushThreadEntry_(Service* const srv, PresentMon* const pm) } } -struct DerivedGpuTelemetry_ -{ - double memUtilization = 0.0; - std::array fanSpeedPercent{}; - size_t fanSpeedPercentCount = 0; -}; - -static DerivedGpuTelemetry_ CalculateDerivedGpuTelemetry_( - const ipc::GpuDataStore& store, - const PresentMonPowerTelemetryInfo& s) noexcept -{ - DerivedGpuTelemetry_ out{}; - if (store.statics.memSize > 0) { - out.memUtilization = 100.0 * (static_cast(s.gpu_mem_used_b) / - static_cast(store.statics.memSize)); - } - - const size_t maxFanCount = store.statics.maxFanSpeedRpm.size(); - const size_t fanCount = std::min(maxFanCount, s.fan_speed_rpm.size()); - out.fanSpeedPercentCount = fanCount; - for (size_t i = 0; i < fanCount; ++i) { - const auto maxRpm = store.statics.maxFanSpeedRpm[i]; - if (maxRpm > 0) { - out.fanSpeedPercent[i] = s.fan_speed_rpm[i] / static_cast(maxRpm); - } - else { - out.fanSpeedPercent[i] = 0.0; - } - } - - return out; -} - -// Translate a single power-telemetry sample into the rings for one GPU store. -// This mirrors the CPU placeholder approach but handles double/uint64/bool rings. -static void PopulateGpuTelemetryRings_( - ipc::GpuDataStore& store, - const PresentMonPowerTelemetryInfo& s) noexcept -{ - const auto derived = CalculateDerivedGpuTelemetry_(store, s); - for (auto&& [metric, ringVariant] : store.telemetryData.Rings()) { - switch (metric) { - - // -------- double metrics -------- - - case PM_METRIC_GPU_POWER: - std::get>(ringVariant)[0] - .Push(s.gpu_power_w, s.qpc); - break; - - case PM_METRIC_GPU_VOLTAGE: - std::get>(ringVariant)[0] - .Push(s.gpu_voltage_v, s.qpc); - break; - - case PM_METRIC_GPU_FREQUENCY: - std::get>(ringVariant)[0] - .Push(s.gpu_frequency_mhz, s.qpc); - break; - - case PM_METRIC_GPU_EFFECTIVE_FREQUENCY: - std::get>(ringVariant)[0] - .Push(s.gpu_effective_frequency_mhz, s.qpc); - break; - - case PM_METRIC_GPU_TEMPERATURE: - std::get>(ringVariant)[0] - .Push(s.gpu_temperature_c, s.qpc); - break; - - case PM_METRIC_GPU_VOLTAGE_REGULATOR_TEMPERATURE: - std::get>(ringVariant)[0] - .Push(s.gpu_voltage_regulator_temperature_c, s.qpc); - break; - - case PM_METRIC_GPU_UTILIZATION: - std::get>(ringVariant)[0] - .Push(s.gpu_utilization, s.qpc); - break; - - case PM_METRIC_GPU_RENDER_COMPUTE_UTILIZATION: - std::get>(ringVariant)[0] - .Push(s.gpu_render_compute_utilization, s.qpc); - break; - - case PM_METRIC_GPU_MEDIA_UTILIZATION: - std::get>(ringVariant)[0] - .Push(s.gpu_media_utilization, s.qpc); - break; - - case PM_METRIC_GPU_MEM_EFFECTIVE_BANDWIDTH: - std::get>(ringVariant)[0] - .Push(s.gpu_mem_effective_bandwidth_gbps, s.qpc); - break; - - case PM_METRIC_GPU_OVERVOLTAGE_PERCENT: - std::get>(ringVariant)[0] - .Push(s.gpu_overvoltage_percent, s.qpc); - break; - - case PM_METRIC_GPU_TEMPERATURE_PERCENT: - std::get>(ringVariant)[0] - .Push(s.gpu_temperature_percent, s.qpc); - break; - - case PM_METRIC_GPU_POWER_PERCENT: - std::get>(ringVariant)[0] - .Push(s.gpu_power_percent, s.qpc); - break; - - case PM_METRIC_GPU_CARD_POWER: - std::get>(ringVariant)[0] - .Push(s.gpu_card_power_w, s.qpc); - break; - - case PM_METRIC_GPU_FAN_SPEED: - { - auto& ringVect = - std::get>(ringVariant); - - const size_t n = std::min(ringVect.size(), s.fan_speed_rpm.size()); - for (size_t i = 0; i < n; ++i) { - ringVect[i].Push(s.fan_speed_rpm[i], s.qpc); - } - break; - } - - case PM_METRIC_GPU_FAN_SPEED_PERCENT: - { - auto& ringVect = - std::get>(ringVariant); - const size_t n = std::min(ringVect.size(), derived.fanSpeedPercentCount); - for (size_t i = 0; i < n; ++i) { - ringVect[i].Push(derived.fanSpeedPercent[i], s.qpc); - } - break; - } - - // VRAM-related doubles - case PM_METRIC_GPU_MEM_POWER: - std::get>(ringVariant)[0] - .Push(s.vram_power_w, s.qpc); - break; - - case PM_METRIC_GPU_MEM_VOLTAGE: - std::get>(ringVariant)[0] - .Push(s.vram_voltage_v, s.qpc); - break; - - case PM_METRIC_GPU_MEM_FREQUENCY: - std::get>(ringVariant)[0] - .Push(s.vram_frequency_mhz, s.qpc); - break; - - case PM_METRIC_GPU_MEM_EFFECTIVE_FREQUENCY: - std::get>(ringVariant)[0] - .Push(s.vram_effective_frequency_gbps, s.qpc); - break; - - case PM_METRIC_GPU_MEM_TEMPERATURE: - std::get>(ringVariant)[0] - .Push(s.vram_temperature_c, s.qpc); - break; - - // Memory bandwidth doubles - case PM_METRIC_GPU_MEM_WRITE_BANDWIDTH: - std::get>(ringVariant)[0] - .Push(s.gpu_mem_write_bandwidth_bps, s.qpc); - break; - - case PM_METRIC_GPU_MEM_READ_BANDWIDTH: - std::get>(ringVariant)[0] - .Push(s.gpu_mem_read_bandwidth_bps, s.qpc); - break; - - case PM_METRIC_GPU_MEM_UTILIZATION: - std::get>(ringVariant)[0] - .Push(derived.memUtilization, s.qpc); - break; - - // -------- uint64 metrics -------- - case PM_METRIC_GPU_MEM_USED: - std::get>(ringVariant)[0] - .Push(s.gpu_mem_used_b, s.qpc); - break; - - // -------- bool metrics -------- - case PM_METRIC_GPU_POWER_LIMITED: - std::get>(ringVariant)[0] - .Push(s.gpu_power_limited, s.qpc); - break; - - case PM_METRIC_GPU_TEMPERATURE_LIMITED: - std::get>(ringVariant)[0] - .Push(s.gpu_temperature_limited, s.qpc); - break; - - case PM_METRIC_GPU_CURRENT_LIMITED: - std::get>(ringVariant)[0] - .Push(s.gpu_current_limited, s.qpc); - break; - - case PM_METRIC_GPU_VOLTAGE_LIMITED: - std::get>(ringVariant)[0] - .Push(s.gpu_voltage_limited, s.qpc); - break; - - case PM_METRIC_GPU_UTILIZATION_LIMITED: - std::get>(ringVariant)[0] - .Push(s.gpu_utilization_limited, s.qpc); - break; - - case PM_METRIC_GPU_MEM_POWER_LIMITED: - std::get>(ringVariant)[0] - .Push(s.vram_power_limited, s.qpc); - break; - - case PM_METRIC_GPU_MEM_TEMPERATURE_LIMITED: - std::get>(ringVariant)[0] - .Push(s.vram_temperature_limited, s.qpc); - break; - - case PM_METRIC_GPU_MEM_CURRENT_LIMITED: - std::get>(ringVariant)[0] - .Push(s.vram_current_limited, s.qpc); - break; - - case PM_METRIC_GPU_MEM_VOLTAGE_LIMITED: - std::get>(ringVariant)[0] - .Push(s.vram_voltage_limited, s.qpc); - break; - - case PM_METRIC_GPU_MEM_UTILIZATION_LIMITED: - std::get>(ringVariant)[0] - .Push(s.vram_utilization_limited, s.qpc); - break; - - default: - pmlog_warn("Unhandled metric").pmwatch((int)metric); - break; - } - } -} - - -void PowerTelemetryThreadEntry_(Service* const srv, PresentMon* const pm, - PowerTelemetryContainer* const ptc, ipc::ServiceComms* const pComms) +void TelemetryThreadEntry_(Service* const srv, PresentMon* const pm, ipc::ServiceComms* const pComms) { using util::win::WaitAnyEvent; using util::win::WaitAnyEventFor; + try { - util::log::IdentificationTable::AddThisThread("tele-gpu"); - pmlog_dbg("Starting gpu telemetry thread"); - if (srv == nullptr || pm == nullptr || ptc == nullptr || pComms == nullptr) { + util::log::IdentificationTable::AddThisThread("telemetry"); + pmlog_dbg("Starting telemetry thread"); + if (srv == nullptr || pm == nullptr || pComms == nullptr) { pmlog_error("Required parameter was null"); return; } - // we first wait for a client control connection before populating telemetry container - // after populating, we refresh each adapter to gather availability information - // this is deferred until client connection in order to increase the probability that - // telemetry metric availability is accurately assessed - { - if (WaitAnyEvent(srv->GetClientSessionHandle(), srv->GetServiceStopHandle()) == 1) { - // if events[1] was signalled, that means service is stopping so exit thread - pmlog_dbg("Exiting gpu telemetry thread before initialization"); - return; - } - pmon::util::QpcTimer timer; - ptc->Repopulate(); - for (auto&& adapter : ptc->GetPowerTelemetryAdapters()) { - const auto deviceId = adapter->GetDeviceId(); - // refresh 2x here as workaround/kludge because Intel provider misreports 1st sample - adapter->Sample(); - const auto sample = adapter->Sample(); - // populate luid information for adapter (currently intel-only) - uint64_t luid = adapter->GetAdapterId(); - std::span luidBytes; - if (luid == 0) { - // if we have no LUID, send empty span - luidBytes = std::span{}; - } - else { - luidBytes = std::span(reinterpret_cast(&luid), sizeof(luid)); - } - pComms->RegisterGpuDevice(deviceId, adapter->GetVendor(), adapter->GetName(), - ipc::intro::ConvertBitset(adapter->GetPowerTelemetryCapBits()), luidBytes); - // after registering, we know that at least the store is available even - // if the introspection itself is not complete - auto& gpuStore = pComms->GetGpuDataStore(deviceId); - // TODO: replace this placeholder routine for populating statics - gpuStore.statics.name = adapter->GetName().c_str(); - gpuStore.statics.vendor = adapter->GetVendor(); - gpuStore.statics.memSize = adapter->GetDedicatedVideoMemory(); - gpuStore.statics.maxMemBandwidth = adapter->GetVideoMemoryMaxBandwidth(); - gpuStore.statics.sustainedPowerLimit = adapter->GetSustainedPowerLimit(); - // max fanspeed is polled in old system but static in new system, shim here - // TODO: make this fully static - // infer number of fans by the size of the telemetry ring array for fan speed - const auto nFans = gpuStore.telemetryData.ArraySize(PM_METRIC_GPU_FAN_SPEED); - for (size_t i = 0; i < nFans; i++) { - gpuStore.statics.maxFanSpeedRpm.push_back(sample.max_fan_speed_rpm[i]); - } - } - pComms->FinalizeGpuDevices(); - pmlog_info(std::format("Finished populating GPU telemetry introspection, {} seconds elapsed", timer.Mark())); - } - - // only start periodic polling when streaming starts - // exit polling loop and this thread when service is stopping - { - IntervalWaiter waiter{ 0.016 }; - while (true) { - pmlog_dbg("(re)starting gpu idle wait"); - if (WaitAnyEvent(pm->GetDeviceUsageEvent(), srv->GetServiceStopHandle()) == 1) { - pmlog_dbg("gpu telemetry received exit code, thread exiting"); - return; - } - else { - // if any of our gpu telemetry devices are active enter polling loop - const auto deviceUsage = pm->GetDeviceMetricUsageSnapshot(); - bool hasActive = false; - for (auto&& adapter : ptc->GetPowerTelemetryAdapters()) { - const auto deviceId = adapter->GetDeviceId(); - if (deviceUsage->contains(deviceId)) { - pmlog_dbg("detected gpu active").pmwatch(deviceId); - hasActive = true; - break; - } - } - if (!hasActive) { - pmlog_dbg("received device usage event, but no gpu tele device was active"); - continue; - } - } - // otherwise we assume streaming has started and we begin the polling loop - // TODO: consider poll loop per device architecture instead of loop all - pmlog_dbg("entering gpu tele active poll loop"); - while (!WaitAnyEventFor(0ms, srv->GetServiceStopHandle())) { - // if device was reset (driver installed etc.) we need to repopulate telemetry - if (WaitAnyEventFor(0ms, srv->GetResetPowerTelemetryHandle())) { - // TODO: log error here or inside of repopulate - ptc->Repopulate(); - } - // poll all gpu adapter devices, skipping inactive devices - auto& adapters = ptc->GetPowerTelemetryAdapters(); - const auto deviceUsage = pm->GetDeviceMetricUsageSnapshot(); - for (auto&& adapter : adapters) { - const auto deviceId = adapter->GetDeviceId(); - if (!deviceUsage->contains(deviceId)) { - continue; - } - // Get the newest sample from the provider - const auto sample = adapter->Sample(); - - // Retrieve the matching GPU store. - auto& store = pComms->GetGpuDataStore(deviceId); - - PopulateGpuTelemetryRings_(store, sample); - } - // Convert from the ms to seconds as GetTelemetryPeriod returns back - // ms and SetInterval expects seconds. - waiter.SetInterval(pm->GetGpuTelemetryPeriod() / 1000.); - waiter.Wait(); - // conditions for ending active poll and returning to idle state - // go dormant if no gpu devices are in use - const bool anyUsed = std::ranges::any_of(adapters, - [&](const auto& adapter) { return deviceUsage->contains(adapter->GetDeviceId()); }); - if (!anyUsed) { - break; - } - } - } - } - } - catch (...) { - pmlog_error(util::ReportException("Exception leaked to top level of gpu telemetry thread")); - } -} - -void CpuTelemetryThreadEntry_(Service* const srv, PresentMon* const pm, ipc::ServiceComms* pComms, - pwr::cpu::CpuTelemetry* const cpu) noexcept -{ - using util::win::WaitAnyEvent; - using util::win::WaitAnyEventFor; - // we don't expect any exceptions in this system during normal operation - // (maybe during initialization at most, not during polling) - // but if they do happen, it is a halting condition for the system telemetry - // don't let this thread crash the process, just exit with an error for later - // diagnosis - try { - util::log::IdentificationTable::AddThisThread("tele-sys"); - pmlog_dbg("Starting system telemetry thread"); - if (srv == nullptr || pm == nullptr || pComms == nullptr || cpu == nullptr) { - pmlog_error("Required parameter was null"); + if (WaitAnyEvent(srv->GetClientSessionHandle(), srv->GetServiceStopHandle()) == 1) { + pmlog_dbg("Exiting telemetry thread before initialization"); return; } + pmon::util::QpcTimer timer; + pmon::tel::TelemetryCoordinator coordinator; + coordinator.RegisterDevicesToIpc(*pComms); + coordinator.PopulateStaticsToIpc(*pComms); + pmlog_info(std::format( + "Finished populating telemetry introspection, {} seconds elapsed", + timer.Mark())); + IntervalWaiter waiter{ 0.016 }; while (true) { - pmlog_dbg("(re)starting system idle wait"); + pmlog_dbg("(re)starting telemetry idle wait"); if (WaitAnyEvent(pm->GetDeviceUsageEvent(), srv->GetServiceStopHandle()) == 1) { - pmlog_dbg("system telemetry received exit code, thread exiting"); + pmlog_dbg("telemetry received exit code, thread exiting"); return; } - else { - // if system telemetry metrics active enter active polling loop - const auto deviceUsage = pm->GetDeviceMetricUsageSnapshot(); - if (deviceUsage->contains(ipc::kSystemDeviceId)) { - pmlog_dbg("detected system active"); - } - else { - pmlog_dbg("received device usage event, but system tele device was not active"); - continue; - } + + auto pMetricUse = pm->GetDeviceMetricUsageSnapshot(); + if (!pMetricUse || pMetricUse->empty()) { + pmlog_dbg("received device usage event, but no telemetry device metrics were active"); + continue; } + + pmlog_dbg("entering telemetry active poll loop"); while (!WaitAnyEventFor(0ms, srv->GetServiceStopHandle())) { - const auto deviceUsage = pm->GetDeviceMetricUsageSnapshot(); - if (!deviceUsage->contains(ipc::kSystemDeviceId)) { - break; + if (WaitAnyEventFor(0ms, srv->GetResetPowerTelemetryHandle())) { + pmlog_warn("Telemetry provider reset requested; live telemetry reprobe is not yet implemented"); } - // TODO:streamer replace this flow with a call that populates rings of a store - // placeholder routine shim to translate cpu tranfer struct into rings - // replace with a direct mapping on PM_METRIC that obviates the switch - auto& store = pComms->GetSystemDataStore(); - const auto sample = cpu->Sample(); - for (auto&& [metric, ringVariant] : store.telemetryData.Rings()) { - // all cpu telemetry is double - auto& ringVect = std::get>(ringVariant); - switch (metric) { - case PM_METRIC_CPU_FREQUENCY: - ringVect[0].Push(sample.cpu_frequency, sample.qpc); - break; - case PM_METRIC_CPU_UTILIZATION: - ringVect[0].Push(sample.cpu_utilization, sample.qpc); - break; - case PM_METRIC_CPU_POWER: - ringVect[0].Push(sample.cpu_power_w, sample.qpc); - break; - case PM_METRIC_CPU_POWER_LIMIT: - ringVect[0].Push(sample.cpu_power_limit_w, sample.qpc); - break; - case PM_METRIC_CPU_TEMPERATURE: - ringVect[0].Push(sample.cpu_temperature, sample.qpc); - break; - default: - pmlog_warn("Unhandled metric ring").pmwatch((int)metric); - break; - } + + pMetricUse = pm->GetDeviceMetricUsageSnapshot(); + if (!pMetricUse || pMetricUse->empty()) { + break; } - // Convert from the ms to seconds as GetTelemetryPeriod returns back - // ms and SetInterval expects seconds. + + coordinator.PollToIpc(*pMetricUse, *pComms); + waiter.SetInterval(pm->GetGpuTelemetryPeriod() / 1000.); waiter.Wait(); } @@ -581,15 +175,12 @@ void CpuTelemetryThreadEntry_(Service* const srv, PresentMon* const pm, ipc::Ser void PresentMonMainThread(Service* const pSvc) { - namespace rn = std::ranges; namespace vi = rn::views; - assert(pSvc); // these thread containers need to be created outside of the try scope // so that if an exception happens, it won't block during unwinding, // trying to join threads that are waiting for a stop signal - std::jthread gpuTelemetryThread; - std::jthread cpuTelemetryThread; + std::jthread telemetryThread; try { LoadNvidiaManifest_(); @@ -599,11 +190,11 @@ void PresentMonMainThread(Service* const pSvc) const auto& reg = Reg::Get(); const auto frameRingSamples = opt.frameRingSamples.AsOptional().value_or( reg.frameRingSamples.AsOptional() - .transform([](auto val) { return static_cast(val); }) + .transform([](auto val) { return (size_t)val; }) .value_or(*opt.frameRingSamples)); const auto telemetryRingSamples = opt.telemetryRingSamples.AsOptional().value_or( reg.telemetryRingSamples.AsOptional() - .transform([](auto val) { return static_cast(val); }) + .transform([](auto val) { return (size_t)val; }) .value_or(*opt.telemetryRingSamples)); // spin here waiting for debugger to attach, after which debugger should set @@ -655,72 +246,15 @@ void PresentMonMainThread(Service* const pSvc) // container for session object PresentMon pm{ frameBroadcaster, !opt.etlTestFile }; - // container for all GPU telemetry providers - PowerTelemetryContainer ptc; - - // Set the created power telemetry container - pm.SetPowerTelemetryContainer(&ptc); // Start named pipe action RPC server (active threaded) auto pActionServer = std::make_unique(pSvc, &pm, opt.controlPipe.AsOptional()); try { - gpuTelemetryThread = std::jthread{ PowerTelemetryThreadEntry_, pSvc, &pm, &ptc, - pComms.get() }; + telemetryThread = std::jthread{ TelemetryThreadEntry_, pSvc, &pm, pComms.get() }; } catch (...) { - LOG(ERROR) << "failed creating gpu(power) telemetry thread" << std::endl; - } - - // Create CPU telemetry - std::shared_ptr cpu; - try { - // Try to use WMI for metrics sampling - cpu = std::make_shared(); - } - catch (const std::runtime_error& e) { - LOG(ERROR) << "failed creating wmi cpu telemetry thread; Status: " << e.what() << std::endl; - } - catch (...) { - LOG(ERROR) << "failed creating wmi cpu telemetry thread" << std::endl; - } - - if (cpu) { - pm.SetCpu(cpu); - // refresh once to populate the cap bits - cpu->Sample(); - // determine vendor based on device name - // TODO: move this logic either into system (CPU) provider or - // into the ipc components - const auto vendor = [&] { - const auto lowerNameRn = cpu->GetCpuName() | vi::transform(tolower); - const std::string lowerName{ lowerNameRn.begin(), lowerNameRn.end() }; - if (lowerName.contains("intel")) { - return PM_DEVICE_VENDOR_INTEL; - } - else if (lowerName.contains("amd")) { - return PM_DEVICE_VENDOR_AMD; - } - else { - return PM_DEVICE_VENDOR_UNKNOWN; - } - }(); - // register cpu - pComms->RegisterCpuDevice(vendor, cpu->GetCpuName(), - ipc::intro::ConvertBitset(cpu->GetCpuTelemetryCapBits())); - // after registering, we know that at least the store is available even - // if the introspection itself is not complete - auto& systemStore = pComms->GetSystemDataStore(); - // TODO: replace this placeholder routine for populating statics - systemStore.statics.cpuName = cpu->GetCpuName().c_str(); - systemStore.statics.cpuPowerLimit = cpu->GetCpuPowerLimit(); - systemStore.statics.cpuVendor = vendor; - cpuTelemetryThread = std::jthread{ CpuTelemetryThreadEntry_, pSvc, &pm, pComms.get(), - cpu.get() }; - } else { - // We were unable to determine the cpu. - pComms->RegisterCpuDevice(PM_DEVICE_VENDOR_UNKNOWN, "UNKNOWN_CPU", - ipc::intro::ConvertBitset(CpuTelemetryBitset{})); + LOG(ERROR) << "failed creating telemetry thread" << std::endl; } // start thread for manual ETW event buffer flushing @@ -740,11 +274,8 @@ void PresentMonMainThread(Service* const pSvc) // Stop the PresentMon sessions pm.StopTraceSessions(); // wait for the telemetry threads to exit - if (gpuTelemetryThread.joinable()) { - gpuTelemetryThread.join(); - } - if (cpuTelemetryThread.joinable()) { - cpuTelemetryThread.join(); + if (telemetryThread.joinable()) { + telemetryThread.join(); } } catch (...) { From 58a6aafbbaf6efcdc39dc275ab8fd62099a79d93 Mon Sep 17 00:00:00 2001 From: Chili Date: Sun, 15 Mar 2026 08:38:05 +0900 Subject: [PATCH 11/42] adl added --- IntelPresentMon/ControlLib/ControlLib.vcxproj | 2 + .../ControlLib/ControlLib.vcxproj.filters | 6 + .../ControlLib/TelemetryCoordinator.cpp | 4 + .../ControlLib/adl/AmdTelemetryProvider.cpp | 900 ++++++++++++++++++ .../ControlLib/adl/AmdTelemetryProvider.h | 124 +++ 5 files changed, 1036 insertions(+) create mode 100644 IntelPresentMon/ControlLib/adl/AmdTelemetryProvider.cpp create mode 100644 IntelPresentMon/ControlLib/adl/AmdTelemetryProvider.h diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj b/IntelPresentMon/ControlLib/ControlLib.vcxproj index ccaaf046..e3fe5ef6 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj @@ -110,6 +110,7 @@ + @@ -148,6 +149,7 @@ + diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters index acbc31bb..cdd7ce8e 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters @@ -73,6 +73,9 @@ Amd + + Amd + Intel @@ -144,6 +147,9 @@ Amd + + Amd + diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp index 6d28f2b7..b26d343d 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp @@ -4,6 +4,7 @@ #include "Exceptions.h" #include "TelemetryDeviceFingerprint.h" #include "Logging.h" +#include "adl/AmdTelemetryProvider.h" #include "igcl/IgclTelemetryProvider.h" #include "nvapi/NvapiTelemetryProvider.h" #include "nvml/NvmlTelemetryProvider.h" @@ -280,6 +281,9 @@ namespace pmon::tel tryAddProvider.operator()( "WMI telemetry provider unavailable", "WMI telemetry provider construction failed"); + tryAddProvider.operator()( + "ADL telemetry provider unavailable", + "ADL telemetry provider construction failed"); tryAddProvider.operator()( "IGCL telemetry provider unavailable", "IGCL telemetry provider construction failed"); diff --git a/IntelPresentMon/ControlLib/adl/AmdTelemetryProvider.cpp b/IntelPresentMon/ControlLib/adl/AmdTelemetryProvider.cpp new file mode 100644 index 00000000..b35b7a5e --- /dev/null +++ b/IntelPresentMon/ControlLib/adl/AmdTelemetryProvider.cpp @@ -0,0 +1,900 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#include "AmdTelemetryProvider.h" + +#include "../Exceptions.h" +#include "../Logging.h" +#include "../../CommonUtilities/Qpc.h" + +#include +#include + +using namespace pmon; +using namespace util; + +namespace pmon::tel::adl +{ + namespace + { + constexpr int kAmdVendorId_ = 1002; + constexpr int kOverdriveVersionMin_ = 5; + constexpr int kOverdriveVersionMax_ = 8; + constexpr int kOdnGpuTemperatureSensor_ = 1; + + bool HasFlag_(int value, int flag) noexcept + { + return (value & flag) == flag; + } + } + + AmdTelemetryProvider::AmdTelemetryProvider() + { + try { + pAdl_ = std::make_unique(); + } + catch (const TelemetrySubsystemAbsent&) { + throw; + } + catch (...) { + pmlog_error(util::ReportException("ADL wrapper construction failed")); + throw Except("Unable to initialize AMD Display Library"); + } + + int adapterCount = 0; + const auto countResult = pAdl_->Adapter_NumberOfAdapters_Get(&adapterCount); + if (!pwr::amd::Adl2Wrapper::Ok(countResult)) { + pmlog_error("ADL2_Adapter_NumberOfAdapters_Get failed").code(countResult); + throw Except<>("ADL adapter count query failed"); + } + + if (adapterCount <= 0) { + return; + } + + std::vector adapterInfos((size_t)adapterCount); + for (auto& adapterInfo : adapterInfos) { + adapterInfo.iSize = sizeof(AdapterInfo); + } + + const auto infoResult = pAdl_->Adapter_AdapterInfo_Get( + adapterInfos.data(), + (int)(adapterInfos.size() * sizeof(AdapterInfo))); + if (!pwr::amd::Adl2Wrapper::Ok(infoResult)) { + pmlog_error("ADL2_Adapter_AdapterInfo_Get failed").code(infoResult); + throw Except<>("ADL adapter info query failed"); + } + + std::unordered_set seenBusNumbers{}; + for (const auto& adapterInfo : adapterInfos) { + if (adapterInfo.iVendorID != kAmdVendorId_) { + continue; + } + if (adapterInfo.iBusNumber < 0) { + pmlog_warn("Skipping AMD adapter with invalid PCI bus number") + .pmwatch(adapterInfo.iAdapterIndex) + .pmwatch(adapterInfo.strAdapterName); + continue; + } + if (!seenBusNumbers.insert(adapterInfo.iBusNumber).second) { + continue; + } + + const auto providerDeviceId = nextProviderDeviceId_; + const auto emplaceResult = devicesById_.try_emplace(providerDeviceId); + if (!emplaceResult.second) { + throw Except<>("Duplicate ADL provider device id encountered"); + } + + auto& device = emplaceResult.first->second; + device.providerDeviceId = providerDeviceId; + if (!TryInitializeDevice_(device, adapterInfo)) { + devicesById_.erase(emplaceResult.first); + continue; + } + + device.caps = BuildCapsForDevice_(device); + ++nextProviderDeviceId_; + } + } + + ProviderCapabilityMap AmdTelemetryProvider::GetCaps() + { + ProviderCapabilityMap capsByDeviceId{}; + for (const auto& entry : devicesById_) { + capsByDeviceId.emplace(entry.first, entry.second.caps); + } + return capsByDeviceId; + } + + const TelemetryDeviceFingerprint& AmdTelemetryProvider::GetFingerPrint( + ProviderDeviceId providerDeviceId) const + { + const auto iDevice = devicesById_.find(providerDeviceId); + if (iDevice == devicesById_.end()) { + throw Except<>("ADL provider device not found"); + } + return iDevice->second.fingerprint; + } + + TelemetryMetricValue AmdTelemetryProvider::PollMetric( + ProviderDeviceId providerDeviceId, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) + { + const auto iDevice = devicesById_.find(providerDeviceId); + if (iDevice == devicesById_.end()) { + throw Except<>("ADL provider device not found"); + } + + auto& device = iDevice->second; + + switch (metricId) { + case PM_METRIC_GPU_VENDOR: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return (int)device.fingerprint.vendor; + case PM_METRIC_GPU_NAME: + throw Except<>("PM_METRIC_GPU_NAME is static-only and is not served by poll path"); + case PM_METRIC_GPU_SUSTAINED_POWER_LIMIT: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto pLimit = QuerySustainedPowerLimit_(device); + return pLimit != nullptr ? *pLimit : 0.0; + } + case PM_METRIC_GPU_MEM_SIZE: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto pMemoryInfo = QueryMemoryInfo_(device); + return pMemoryInfo != nullptr ? GetMemorySizeBytes_(*pMemoryInfo) : (uint64_t)0; + } + case PM_METRIC_GPU_MEM_MAX_BANDWIDTH: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto pMemoryInfo = QueryMemoryInfo_(device); + return pMemoryInfo != nullptr ? GetMemoryMaxBandwidthBitsPerSecond_(*pMemoryInfo) : (uint64_t)0; + } + default: + break; + } + + const auto& snapshot = PollDynamicSnapshot_(device, requestQpc); + + switch (metricId) { + case PM_METRIC_GPU_POWER: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return snapshot.hasGpuPower ? snapshot.gpuPowerW : 0.0; + case PM_METRIC_GPU_VOLTAGE: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return snapshot.hasGpuVoltage ? snapshot.gpuVoltageV : 0.0; + case PM_METRIC_GPU_FREQUENCY: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return snapshot.hasGpuFrequency ? snapshot.gpuFrequencyMhz : 0.0; + case PM_METRIC_GPU_TEMPERATURE: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return snapshot.hasGpuTemperature ? snapshot.gpuTemperatureC : 0.0; + case PM_METRIC_GPU_UTILIZATION: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return snapshot.hasGpuUtilization ? snapshot.gpuUtilizationPercent : 0.0; + case PM_METRIC_GPU_MEM_FREQUENCY: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return snapshot.hasGpuMemFrequency ? snapshot.gpuMemFrequencyMhz : 0.0; + case PM_METRIC_GPU_MEM_USED: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return snapshot.hasGpuMemUsed ? snapshot.gpuMemUsedBytes : (uint64_t)0; + case PM_METRIC_GPU_MEM_UTILIZATION: + { + ValidateScalarMetricIndex_(metricId, arrayIndex); + const auto pMemoryInfo = QueryMemoryInfo_(device); + if (!snapshot.hasGpuMemUsed || pMemoryInfo == nullptr) { + return 0.0; + } + const auto totalBytes = GetMemorySizeBytes_(*pMemoryInfo); + if (totalBytes == 0) { + return 0.0; + } + return 100.0 * ((double)snapshot.gpuMemUsedBytes / (double)totalBytes); + } + case PM_METRIC_GPU_MEM_TEMPERATURE: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return snapshot.hasGpuMemTemperature ? snapshot.gpuMemTemperatureC : 0.0; + case PM_METRIC_GPU_MEM_VOLTAGE: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return snapshot.hasGpuMemVoltage ? snapshot.gpuMemVoltageV : 0.0; + case PM_METRIC_GPU_POWER_LIMITED: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return snapshot.hasThrottleStatus ? snapshot.gpuPowerLimited : false; + case PM_METRIC_GPU_TEMPERATURE_LIMITED: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return snapshot.hasThrottleStatus ? snapshot.gpuTemperatureLimited : false; + case PM_METRIC_GPU_CURRENT_LIMITED: + ValidateScalarMetricIndex_(metricId, arrayIndex); + return snapshot.hasThrottleStatus ? snapshot.gpuCurrentLimited : false; + case PM_METRIC_GPU_FAN_SPEED: + if (arrayIndex >= snapshot.fanSpeedsRpm.size()) { + throw Except<>("ADL array index out of range"); + } + return snapshot.fanSpeedsRpm[(size_t)arrayIndex]; + case PM_METRIC_GPU_FAN_SPEED_PERCENT: + if (arrayIndex >= snapshot.fanSpeedRatios.size()) { + throw Except<>("ADL array index out of range"); + } + return snapshot.fanSpeedRatios[(size_t)arrayIndex]; + default: + throw Except<>("Unsupported metric for ADL provider"); + } + } + + void AmdTelemetryProvider::ValidateScalarMetricIndex_(PM_METRIC metricId, uint32_t arrayIndex) + { + if (arrayIndex != 0) { + throw Except<>("ADL scalar metric queried with nonzero array index"); + } + (void)metricId; + } + + uint64_t AmdTelemetryProvider::GetMemorySizeBytes_(const ADLMemoryInfoX4& memoryInfo) noexcept + { + return memoryInfo.iMemorySize > 0 ? (uint64_t)memoryInfo.iMemorySize : 0ull; + } + + uint64_t AmdTelemetryProvider::GetMemoryMaxBandwidthBitsPerSecond_(const ADLMemoryInfoX4& memoryInfo) noexcept + { + if (memoryInfo.iMemoryBitRateX2 > 0) { + return (uint64_t)memoryInfo.iMemoryBitRateX2; + } + if (memoryInfo.iMemoryBandwidthX2 > 0) { + return (uint64_t)memoryInfo.iMemoryBandwidthX2 * 8ull; + } + if (memoryInfo.iMemoryBandwidth > 0) { + return (uint64_t)memoryInfo.iMemoryBandwidth * 8ull * 1000000ull; + } + return 0ull; + } + + bool AmdTelemetryProvider::TryGetPmLogSensorValue_( + const ADLPMLogDataOutput& data, + int sensorIndex, + int& value) noexcept + { + if (sensorIndex < 0 || sensorIndex >= ADL_PMLOG_MAX_SENSORS) { + value = 0; + return false; + } + + const auto& sensor = data.sensors[(size_t)sensorIndex]; + if (!sensor.supported) { + value = 0; + return false; + } + + value = sensor.value; + return true; + } + + bool AmdTelemetryProvider::TryInitializeDevice_( + DeviceState_& device, + const AdapterInfo& adapterInfo) const + { + device.adlAdapterIndex = adapterInfo.iAdapterIndex; + device.fingerprint.deviceType = PM_DEVICE_TYPE_GRAPHICS_ADAPTER; + device.fingerprint.vendor = PM_DEVICE_VENDOR_AMD; + device.fingerprint.deviceName = + adapterInfo.strAdapterName[0] != '\0' ? adapterInfo.strAdapterName : "Unknown AMD Adapter"; + device.fingerprint.pciBusId = (uint32_t)adapterInfo.iBusNumber; + + int overdriveSupported = 0; + int overdriveEnabled = 0; + int overdriveVersion = 0; + const auto capsResult = pAdl_->Overdrive_Caps( + device.adlAdapterIndex, + &overdriveSupported, + &overdriveEnabled, + &overdriveVersion); + if (!pwr::amd::Adl2Wrapper::Ok(capsResult)) { + pmlog_warn("ADL2_Overdrive_Caps failed").code(capsResult) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + return false; + } + + if (!overdriveSupported || !overdriveEnabled) { + pmlog_warn("Skipping AMD adapter without enabled Overdrive telemetry") + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName) + .pmwatch(overdriveSupported) + .pmwatch(overdriveEnabled); + return false; + } + + if (overdriveVersion < kOverdriveVersionMin_ || overdriveVersion > kOverdriveVersionMax_) { + pmlog_warn("Skipping AMD adapter with unsupported Overdrive version") + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName) + .pmwatch(overdriveVersion); + return false; + } + + device.overdriveVersion = overdriveVersion; + if (device.overdriveVersion == 5) { + EnumerateOd5ThermalControllers_(device); + } + + return true; + } + + void AmdTelemetryProvider::EnumerateOd5ThermalControllers_(DeviceState_& device) const + { + device.od5ThermalControllerIndices.clear(); + + for (int thermalControllerIndex = 0; thermalControllerIndex < 10; ++thermalControllerIndex) { + ADLThermalControllerInfo thermalInfo{ .iSize = sizeof(ADLThermalControllerInfo) }; + const auto result = pAdl_->Overdrive5_ThermalDevices_Enum( + device.adlAdapterIndex, + thermalControllerIndex, + &thermalInfo); + if (!pwr::amd::Adl2Wrapper::Ok(result)) { + if (result != ADL_ERR_INVALID_CONTROLLER_IDX && result != ADL_ERR) { + pmlog_warn("ADL2_Overdrive5_ThermalDevices_Enum failed").code(result) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName) + .pmwatch(thermalControllerIndex); + } + break; + } + if (thermalInfo.iThermalDomain == ADL_DL_THERMAL_DOMAIN_GPU) { + device.od5ThermalControllerIndices.push_back(thermalControllerIndex); + } + } + } + + ipc::MetricCapabilities AmdTelemetryProvider::BuildCapsForDevice_(DeviceState_& device) const + { + ipc::MetricCapabilities caps{}; + const auto requestQpc = GetCurrentTimestamp(); + + caps.Set(PM_METRIC_GPU_VENDOR, 1); + caps.Set(PM_METRIC_GPU_NAME, 1); + + if (QuerySustainedPowerLimit_(device) != nullptr) { + caps.Set(PM_METRIC_GPU_SUSTAINED_POWER_LIMIT, 1); + } + + if (const auto pMemoryInfo = QueryMemoryInfo_(device); pMemoryInfo != nullptr) { + const auto memSize = GetMemorySizeBytes_(*pMemoryInfo); + const auto memBw = GetMemoryMaxBandwidthBitsPerSecond_(*pMemoryInfo); + if (memSize != 0) { + caps.Set(PM_METRIC_GPU_MEM_SIZE, 1); + } + if (memBw != 0) { + caps.Set(PM_METRIC_GPU_MEM_MAX_BANDWIDTH, 1); + } + } + + const auto& snapshot = PollDynamicSnapshot_(device, requestQpc); + if (snapshot.hasGpuPower) { + caps.Set(PM_METRIC_GPU_POWER, 1); + } + if (snapshot.hasGpuVoltage) { + caps.Set(PM_METRIC_GPU_VOLTAGE, 1); + } + if (snapshot.hasGpuFrequency) { + caps.Set(PM_METRIC_GPU_FREQUENCY, 1); + } + if (snapshot.hasGpuTemperature) { + caps.Set(PM_METRIC_GPU_TEMPERATURE, 1); + } + if (snapshot.hasGpuUtilization) { + caps.Set(PM_METRIC_GPU_UTILIZATION, 1); + } + if (snapshot.hasGpuMemFrequency) { + caps.Set(PM_METRIC_GPU_MEM_FREQUENCY, 1); + } + if (snapshot.hasGpuMemUsed) { + caps.Set(PM_METRIC_GPU_MEM_USED, 1); + if (const auto pMemoryInfo = QueryMemoryInfo_(device); + pMemoryInfo != nullptr && GetMemorySizeBytes_(*pMemoryInfo) != 0) { + caps.Set(PM_METRIC_GPU_MEM_UTILIZATION, 1); + } + } + if (snapshot.hasGpuMemTemperature) { + caps.Set(PM_METRIC_GPU_MEM_TEMPERATURE, 1); + } + if (snapshot.hasGpuMemVoltage) { + caps.Set(PM_METRIC_GPU_MEM_VOLTAGE, 1); + } + if (!snapshot.fanSpeedsRpm.empty()) { + caps.Set(PM_METRIC_GPU_FAN_SPEED, (uint32_t)snapshot.fanSpeedsRpm.size()); + } + if (!snapshot.fanSpeedRatios.empty()) { + caps.Set(PM_METRIC_GPU_FAN_SPEED_PERCENT, (uint32_t)snapshot.fanSpeedRatios.size()); + } + if (snapshot.hasThrottleStatus) { + caps.Set(PM_METRIC_GPU_POWER_LIMITED, 1); + caps.Set(PM_METRIC_GPU_TEMPERATURE_LIMITED, 1); + caps.Set(PM_METRIC_GPU_CURRENT_LIMITED, 1); + } + + return caps; + } + + const ADLMemoryInfoX4* AmdTelemetryProvider::QueryMemoryInfo_(DeviceState_& device) const + { + if (device.memoryInfoQueried) { + return device.memoryInfo ? &*device.memoryInfo : nullptr; + } + + device.memoryInfoQueried = true; + ADLMemoryInfoX4 memoryInfo{}; + const auto result = pAdl_->Adapter_MemoryInfoX4_Get(device.adlAdapterIndex, &memoryInfo); + if (!pwr::amd::Adl2Wrapper::Ok(result)) { + pmlog_warn("ADL2_Adapter_MemoryInfoX4_Get failed").code(result) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + return nullptr; + } + + device.memoryInfo = memoryInfo; + return &*device.memoryInfo; + } + + const double* AmdTelemetryProvider::QuerySustainedPowerLimit_(DeviceState_& device) const + { + if (device.sustainedPowerLimitQueried) { + return device.sustainedPowerLimitW ? &*device.sustainedPowerLimitW : nullptr; + } + + device.sustainedPowerLimitQueried = true; + + switch (device.overdriveVersion) { + case 5: + { + int powerControlSupported = 0; + auto result = pAdl_->Overdrive5_PowerControl_Caps( + device.adlAdapterIndex, + &powerControlSupported); + if (!pwr::amd::Adl2Wrapper::Ok(result)) { + pmlog_warn("ADL2_Overdrive5_PowerControl_Caps failed").code(result) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + return nullptr; + } + if (!powerControlSupported) { + return nullptr; + } + + int powerControlCurrent = 0; + int powerControlDefault = 0; + result = pAdl_->Overdrive5_PowerControl_Get( + device.adlAdapterIndex, + &powerControlCurrent, + &powerControlDefault); + if (!pwr::amd::Adl2Wrapper::Ok(result)) { + pmlog_warn("ADL2_Overdrive5_PowerControl_Get failed").code(result) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + return nullptr; + } + + device.sustainedPowerLimitW = (double)powerControlCurrent; + (void)powerControlDefault; + return &*device.sustainedPowerLimitW; + } + case 6: + { + int powerControlSupported = 0; + auto result = pAdl_->Overdrive6_PowerControl_Caps( + device.adlAdapterIndex, + &powerControlSupported); + if (!pwr::amd::Adl2Wrapper::Ok(result)) { + pmlog_warn("ADL2_Overdrive6_PowerControl_Caps failed").code(result) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + return nullptr; + } + if (!powerControlSupported) { + return nullptr; + } + + int powerControlCurrent = 0; + int powerControlDefault = 0; + result = pAdl_->Overdrive6_PowerControl_Get( + device.adlAdapterIndex, + &powerControlCurrent, + &powerControlDefault); + if (!pwr::amd::Adl2Wrapper::Ok(result)) { + pmlog_warn("ADL2_Overdrive6_PowerControl_Get failed").code(result) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + return nullptr; + } + + device.sustainedPowerLimitW = (double)powerControlCurrent; + (void)powerControlDefault; + return &*device.sustainedPowerLimitW; + } + default: + return nullptr; + } + } + + const AmdTelemetryProvider::DynamicSnapshot_& AmdTelemetryProvider::PollDynamicSnapshot_( + DeviceState_& device, + int64_t requestQpc) const + { + auto& cache = device.dynamicSnapshotCache; + if (cache.Matches(requestQpc)) { + return cache.output; + } + + cache.output = {}; + cache.requestQpc = requestQpc; + auto& snapshot = cache.output; + + int vramUsageMb = 0; + const auto vramUsageResult = pAdl_->Adapter_VRAMUsage_Get(device.adlAdapterIndex, &vramUsageMb); + if (pwr::amd::Adl2Wrapper::Ok(vramUsageResult)) { + snapshot.hasGpuMemUsed = true; + snapshot.gpuMemUsedBytes = (uint64_t)vramUsageMb * 1000000ull; + } + else { + pmlog_warn("ADL2_Adapter_VRAMUsage_Get failed").code(vramUsageResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + } + + switch (device.overdriveVersion) { + case 5: + PopulateOverdrive5Snapshot_(device, snapshot); + break; + case 6: + PopulateOverdrive6Snapshot_(device, snapshot); + break; + case 7: + PopulateOverdrive7Snapshot_(device, snapshot); + break; + case 8: + PopulateOverdrive8Snapshot_(device, snapshot); + break; + default: + pmlog_warn("Unexpected ADL Overdrive version while polling snapshot") + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName) + .pmwatch(device.overdriveVersion); + break; + } + + return cache.output; + } + + void AmdTelemetryProvider::PopulateOverdrive5Snapshot_( + DeviceState_& device, + DynamicSnapshot_& snapshot) const + { + for (const auto thermalControllerIndex : device.od5ThermalControllerIndices) { + ADLTemperature temperature{ .iSize = sizeof(ADLTemperature) }; + const auto tempResult = pAdl_->Overdrive5_Temperature_Get( + device.adlAdapterIndex, + thermalControllerIndex, + &temperature); + if (pwr::amd::Adl2Wrapper::Ok(tempResult)) { + if (!snapshot.hasGpuTemperature) { + snapshot.gpuTemperatureC = (double)temperature.iTemperature / 1000.0; + snapshot.hasGpuTemperature = true; + } + } + else { + pmlog_warn("ADL2_Overdrive5_Temperature_Get failed").code(tempResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName) + .pmwatch(thermalControllerIndex); + } + + ADLFanSpeedInfo fanInfo{ .iSize = sizeof(ADLFanSpeedInfo) }; + const auto fanInfoResult = pAdl_->Overdrive5_FanSpeedInfo_Get( + device.adlAdapterIndex, + thermalControllerIndex, + &fanInfo); + if (!pwr::amd::Adl2Wrapper::Ok(fanInfoResult)) { + pmlog_warn("ADL2_Overdrive5_FanSpeedInfo_Get failed").code(fanInfoResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName) + .pmwatch(thermalControllerIndex); + continue; + } + + if (HasFlag_(fanInfo.iFlags, ADL_DL_FANCTRL_SUPPORTS_RPM_READ)) { + ADLFanSpeedValue fanValue{ + .iSize = sizeof(ADLFanSpeedValue), + .iSpeedType = ADL_DL_FANCTRL_SPEED_TYPE_RPM, + }; + const auto fanResult = pAdl_->Overdrive5_FanSpeed_Get( + device.adlAdapterIndex, + thermalControllerIndex, + &fanValue); + if (pwr::amd::Adl2Wrapper::Ok(fanResult)) { + snapshot.fanSpeedsRpm.push_back((double)fanValue.iFanSpeed); + } + else { + pmlog_warn("ADL2_Overdrive5_FanSpeed_Get failed for RPM").code(fanResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName) + .pmwatch(thermalControllerIndex); + } + } + + if (HasFlag_(fanInfo.iFlags, ADL_DL_FANCTRL_SUPPORTS_PERCENT_READ)) { + ADLFanSpeedValue fanValue{ + .iSize = sizeof(ADLFanSpeedValue), + .iSpeedType = ADL_DL_FANCTRL_SPEED_TYPE_PERCENT, + }; + const auto fanResult = pAdl_->Overdrive5_FanSpeed_Get( + device.adlAdapterIndex, + thermalControllerIndex, + &fanValue); + if (pwr::amd::Adl2Wrapper::Ok(fanResult)) { + snapshot.fanSpeedRatios.push_back((double)fanValue.iFanSpeed / 100.0); + } + else { + pmlog_warn("ADL2_Overdrive5_FanSpeed_Get failed for percent").code(fanResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName) + .pmwatch(thermalControllerIndex); + } + } + } + + ADLPMActivity activity{ .iSize = sizeof(ADLPMActivity) }; + const auto activityResult = pAdl_->Overdrive5_CurrentActivity_Get( + device.adlAdapterIndex, + &activity); + if (pwr::amd::Adl2Wrapper::Ok(activityResult)) { + snapshot.gpuUtilizationPercent = (double)activity.iActivityPercent; + snapshot.hasGpuUtilization = true; + + snapshot.gpuFrequencyMhz = (double)activity.iEngineClock / 100.0; + snapshot.hasGpuFrequency = true; + + snapshot.gpuMemFrequencyMhz = (double)activity.iMemoryClock / 100.0; + snapshot.hasGpuMemFrequency = true; + + snapshot.gpuVoltageV = (double)activity.iVddc; + snapshot.hasGpuVoltage = true; + } + else { + pmlog_warn("ADL2_Overdrive5_CurrentActivity_Get failed").code(activityResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + } + } + + void AmdTelemetryProvider::PopulateOverdrive6Snapshot_( + DeviceState_& device, + DynamicSnapshot_& snapshot) const + { + ADLOD6ThermalControllerCaps thermalCaps{}; + const auto thermalCapsResult = pAdl_->Overdrive6_ThermalController_Caps( + device.adlAdapterIndex, + &thermalCaps); + if (pwr::amd::Adl2Wrapper::Ok(thermalCapsResult)) { + if (HasFlag_(thermalCaps.iCapabilities, ADL_OD6_TCCAPS_THERMAL_CONTROLLER)) { + int temperature = 0; + const auto tempResult = pAdl_->Overdrive6_Temperature_Get(device.adlAdapterIndex, &temperature); + if (pwr::amd::Adl2Wrapper::Ok(tempResult)) { + snapshot.gpuTemperatureC = (double)temperature / 1000.0; + snapshot.hasGpuTemperature = true; + } + else { + pmlog_warn("ADL2_Overdrive6_Temperature_Get failed").code(tempResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + } + } + + ADLOD6FanSpeedInfo fanInfo{}; + const auto fanResult = pAdl_->Overdrive6_FanSpeed_Get(device.adlAdapterIndex, &fanInfo); + if (pwr::amd::Adl2Wrapper::Ok(fanResult)) { + if (HasFlag_(fanInfo.iSpeedType, ADL_OD6_FANSPEED_TYPE_RPM)) { + snapshot.fanSpeedsRpm.push_back((double)fanInfo.iFanSpeedRPM); + } + if (HasFlag_(fanInfo.iSpeedType, ADL_OD6_FANSPEED_TYPE_PERCENT)) { + snapshot.fanSpeedRatios.push_back((double)fanInfo.iFanSpeedPercent / 100.0); + } + } + else { + pmlog_warn("ADL2_Overdrive6_FanSpeed_Get failed").code(fanResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + } + } + else { + pmlog_warn("ADL2_Overdrive6_ThermalController_Caps failed").code(thermalCapsResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + } + + ADLOD6CurrentStatus currentStatus{}; + const auto currentStatusResult = pAdl_->Overdrive6_CurrentStatus_Get(device.adlAdapterIndex, ¤tStatus); + if (pwr::amd::Adl2Wrapper::Ok(currentStatusResult)) { + snapshot.gpuFrequencyMhz = (double)currentStatus.iEngineClock / 100.0; + snapshot.hasGpuFrequency = true; + + snapshot.gpuMemFrequencyMhz = (double)currentStatus.iMemoryClock / 100.0; + snapshot.hasGpuMemFrequency = true; + + ADLOD6Capabilities capabilities{}; + const auto capResult = pAdl_->Overdrive6_Capabilities_Get(device.adlAdapterIndex, &capabilities); + if (pwr::amd::Adl2Wrapper::Ok(capResult)) { + if (HasFlag_(capabilities.iCapabilities, ADL_OD6_CAPABILITY_GPU_ACTIVITY_MONITOR)) { + snapshot.gpuUtilizationPercent = (double)currentStatus.iActivityPercent; + snapshot.hasGpuUtilization = true; + } + } + else { + pmlog_warn("ADL2_Overdrive6_Capabilities_Get failed").code(capResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + } + } + else { + pmlog_warn("ADL2_Overdrive6_CurrentStatus_Get failed").code(currentStatusResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + } + + int currentPower = 0; + const auto powerResult = pAdl_->Overdrive6_CurrentPower_Get(device.adlAdapterIndex, 0, ¤tPower); + if (pwr::amd::Adl2Wrapper::Ok(powerResult)) { + snapshot.gpuPowerW = (double)currentPower / 256.0; + snapshot.hasGpuPower = true; + } + else { + pmlog_warn("ADL2_Overdrive6_CurrentPower_Get failed").code(powerResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + } + } + + void AmdTelemetryProvider::PopulateOverdrive7Snapshot_( + DeviceState_& device, + DynamicSnapshot_& snapshot) const + { + ADLODNCapabilitiesX2 capabilities{}; + const auto capsResult = pAdl_->OverdriveN_CapabilitiesX2_Get(device.adlAdapterIndex, &capabilities); + if (!pwr::amd::Adl2Wrapper::Ok(capsResult)) { + pmlog_warn("ADL2_OverdriveN_CapabilitiesX2_Get failed").code(capsResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + return; + } + + ADLODNPerformanceStatus performanceStatus{}; + const auto statusResult = pAdl_->OverdriveN_PerformanceStatus_Get(device.adlAdapterIndex, &performanceStatus); + if (pwr::amd::Adl2Wrapper::Ok(statusResult)) { + snapshot.gpuFrequencyMhz = (double)performanceStatus.iCoreClock / 100.0; + snapshot.hasGpuFrequency = true; + + snapshot.gpuMemFrequencyMhz = (double)performanceStatus.iMemoryClock / 100.0; + snapshot.hasGpuMemFrequency = true; + + snapshot.gpuVoltageV = (double)performanceStatus.iVDDC / 1000.0; + snapshot.hasGpuVoltage = true; + + snapshot.gpuUtilizationPercent = (double)performanceStatus.iGPUActivityPercent; + snapshot.hasGpuUtilization = true; + } + else { + pmlog_warn("ADL2_OverdriveN_PerformanceStatus_Get failed").code(statusResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + } + + int temperature = 0; + const auto tempResult = pAdl_->OverdriveN_Temperature_Get( + device.adlAdapterIndex, + kOdnGpuTemperatureSensor_, + &temperature); + if (pwr::amd::Adl2Wrapper::Ok(tempResult)) { + snapshot.gpuTemperatureC = (double)temperature / 1000.0; + snapshot.hasGpuTemperature = true; + } + else { + pmlog_warn("ADL2_OverdriveN_Temperature_Get failed").code(tempResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + } + + ADLODNFanControl fanControl{}; + const auto fanResult = pAdl_->OverdriveN_FanControl_Get(device.adlAdapterIndex, &fanControl); + if (pwr::amd::Adl2Wrapper::Ok(fanResult)) { + if (HasFlag_(fanControl.iCurrentFanSpeedMode, ADL_OD6_FANSPEED_TYPE_RPM)) { + snapshot.fanSpeedsRpm.push_back((double)fanControl.iCurrentFanSpeed); + } + else if (HasFlag_(fanControl.iCurrentFanSpeedMode, ADL_OD6_FANSPEED_TYPE_PERCENT)) { + snapshot.fanSpeedRatios.push_back((double)fanControl.iCurrentFanSpeed / 100.0); + } + else { + snapshot.fanSpeedsRpm.push_back((double)fanControl.iCurrentFanSpeed); + } + } + else { + pmlog_warn("ADL2_OverdriveN_FanControl_Get failed").code(fanResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + } + + int currentPower = 0; + const auto powerResult = pAdl_->Overdrive6_CurrentPower_Get(device.adlAdapterIndex, 0, ¤tPower); + if (pwr::amd::Adl2Wrapper::Ok(powerResult)) { + snapshot.gpuPowerW = (double)currentPower / 256.0; + snapshot.hasGpuPower = true; + } + else { + pmlog_warn("ADL2_Overdrive6_CurrentPower_Get failed").code(powerResult).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + } + + (void)capabilities; + } + + void AmdTelemetryProvider::PopulateOverdrive8Snapshot_( + DeviceState_& device, + DynamicSnapshot_& snapshot) const + { + ADLPMLogDataOutput dataOutput{}; + dataOutput.size = sizeof(ADLPMLogDataOutput); + const auto result = pAdl_->New_QueryPMLogData_Get(device.adlAdapterIndex, &dataOutput); + if (!pwr::amd::Adl2Wrapper::Ok(result)) { + pmlog_warn("ADL2_New_QueryPMLogData_Get failed").code(result).every(std::chrono::seconds{ 60 }) + .pmwatch(device.providerDeviceId) + .pmwatch(device.fingerprint.deviceName); + return; + } + + int value = 0; + if (TryGetPmLogSensorValue_(dataOutput, PMLOG_CLK_GFXCLK, value)) { + snapshot.gpuFrequencyMhz = (double)value; + snapshot.hasGpuFrequency = true; + } + if (TryGetPmLogSensorValue_(dataOutput, PMLOG_CLK_MEMCLK, value)) { + snapshot.gpuMemFrequencyMhz = (double)value; + snapshot.hasGpuMemFrequency = true; + } + if (TryGetPmLogSensorValue_(dataOutput, PMLOG_FAN_RPM, value)) { + snapshot.fanSpeedsRpm.push_back((double)value); + } + if (TryGetPmLogSensorValue_(dataOutput, PMLOG_FAN_PERCENTAGE, value)) { + snapshot.fanSpeedRatios.push_back((double)value / 100.0); + } + if (TryGetPmLogSensorValue_(dataOutput, PMLOG_TEMPERATURE_EDGE, value)) { + snapshot.gpuTemperatureC = (double)value; + snapshot.hasGpuTemperature = true; + } + if (TryGetPmLogSensorValue_(dataOutput, PMLOG_INFO_ACTIVITY_GFX, value)) { + snapshot.gpuUtilizationPercent = (double)value; + snapshot.hasGpuUtilization = true; + } + if (TryGetPmLogSensorValue_(dataOutput, PMLOG_GFX_VOLTAGE, value)) { + snapshot.gpuVoltageV = (double)value / 1000.0; + snapshot.hasGpuVoltage = true; + } + if (TryGetPmLogSensorValue_(dataOutput, PMLOG_ASIC_POWER, value)) { + snapshot.gpuPowerW = (double)value; + snapshot.hasGpuPower = true; + } + if (TryGetPmLogSensorValue_(dataOutput, PMLOG_TEMPERATURE_MEM, value)) { + snapshot.gpuMemTemperatureC = (double)value; + snapshot.hasGpuMemTemperature = true; + } + if (TryGetPmLogSensorValue_(dataOutput, PMLOG_MEM_VOLTAGE, value)) { + snapshot.gpuMemVoltageV = (double)value / 1000.0; + snapshot.hasGpuMemVoltage = true; + } + if (TryGetPmLogSensorValue_(dataOutput, PMLOG_THROTTLER_STATUS, value)) { + snapshot.hasThrottleStatus = true; + snapshot.gpuPowerLimited = HasFlag_(value, ADL_PMLOG_THROTTLE_POWER); + snapshot.gpuTemperatureLimited = HasFlag_(value, ADL_PMLOG_THROTTLE_THERMAL); + snapshot.gpuCurrentLimited = HasFlag_(value, ADL_PMLOG_THROTTLE_CURRENT); + } + } +} diff --git a/IntelPresentMon/ControlLib/adl/AmdTelemetryProvider.h b/IntelPresentMon/ControlLib/adl/AmdTelemetryProvider.h new file mode 100644 index 00000000..fefb90b5 --- /dev/null +++ b/IntelPresentMon/ControlLib/adl/AmdTelemetryProvider.h @@ -0,0 +1,124 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#pragma once + +#include "../Adl2Wrapper.h" +#include "../EndpointCache.h" +#include "../TelemetryProvider.h" + +#include +#include +#include +#include +#include + +namespace pmon::tel::adl +{ + class AmdTelemetryProvider : public TelemetryProvider + { + public: + AmdTelemetryProvider(); + ~AmdTelemetryProvider() override = default; + ProviderCapabilityMap GetCaps() override; + const TelemetryDeviceFingerprint& GetFingerPrint(ProviderDeviceId providerDeviceId) const override; + TelemetryMetricValue PollMetric( + ProviderDeviceId providerDeviceId, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) override; + + private: + struct DynamicSnapshot_ + { + bool hasGpuPower = false; + double gpuPowerW = 0.0; + + bool hasGpuVoltage = false; + double gpuVoltageV = 0.0; + + bool hasGpuFrequency = false; + double gpuFrequencyMhz = 0.0; + + bool hasGpuTemperature = false; + double gpuTemperatureC = 0.0; + + bool hasGpuUtilization = false; + double gpuUtilizationPercent = 0.0; + + bool hasGpuMemFrequency = false; + double gpuMemFrequencyMhz = 0.0; + + bool hasGpuMemUsed = false; + uint64_t gpuMemUsedBytes = 0; + + bool hasGpuMemTemperature = false; + double gpuMemTemperatureC = 0.0; + + bool hasGpuMemVoltage = false; + double gpuMemVoltageV = 0.0; + + bool hasThrottleStatus = false; + bool gpuPowerLimited = false; + bool gpuTemperatureLimited = false; + bool gpuCurrentLimited = false; + + std::vector fanSpeedsRpm{}; + std::vector fanSpeedRatios{}; + }; + + struct DeviceState_ + { + ProviderDeviceId providerDeviceId = 0; + TelemetryDeviceFingerprint fingerprint{}; + ipc::MetricCapabilities caps{}; + + int adlAdapterIndex = -1; + int overdriveVersion = 0; + std::vector od5ThermalControllerIndices{}; + + bool memoryInfoQueried = false; + std::optional memoryInfo{}; + + bool sustainedPowerLimitQueried = false; + std::optional sustainedPowerLimitW{}; + + pmon::tele::EndpointCache dynamicSnapshotCache{}; + }; + + static void ValidateScalarMetricIndex_(PM_METRIC metricId, uint32_t arrayIndex); + static uint64_t GetMemorySizeBytes_(const ADLMemoryInfoX4& memoryInfo) noexcept; + static uint64_t GetMemoryMaxBandwidthBitsPerSecond_(const ADLMemoryInfoX4& memoryInfo) noexcept; + static bool TryGetPmLogSensorValue_( + const ADLPMLogDataOutput& data, + int sensorIndex, + int& value) noexcept; + + bool TryInitializeDevice_(DeviceState_& device, const AdapterInfo& adapterInfo) const; + void EnumerateOd5ThermalControllers_(DeviceState_& device) const; + ipc::MetricCapabilities BuildCapsForDevice_(DeviceState_& device) const; + + const ADLMemoryInfoX4* QueryMemoryInfo_(DeviceState_& device) const; + const double* QuerySustainedPowerLimit_(DeviceState_& device) const; + const DynamicSnapshot_& PollDynamicSnapshot_( + DeviceState_& device, + int64_t requestQpc) const; + + void PopulateOverdrive5Snapshot_( + DeviceState_& device, + DynamicSnapshot_& snapshot) const; + void PopulateOverdrive6Snapshot_( + DeviceState_& device, + DynamicSnapshot_& snapshot) const; + void PopulateOverdrive7Snapshot_( + DeviceState_& device, + DynamicSnapshot_& snapshot) const; + void PopulateOverdrive8Snapshot_( + DeviceState_& device, + DynamicSnapshot_& snapshot) const; + + private: + std::unique_ptr pAdl_{}; + std::unordered_map devicesById_{}; + ProviderDeviceId nextProviderDeviceId_ = 1; + }; +} From 4d95387a05d64a65f25aae55eecd639c2c7ffcb9 Mon Sep 17 00:00:00 2001 From: Chili Date: Sun, 15 Mar 2026 09:36:48 +0900 Subject: [PATCH 12/42] move remaining 3rd party, delete bitset, shims, legacy provider/adapter --- .../ref/gen/GeneratedReflection.h | 2 +- .../ControlLib/AmdPowerTelemetryAdapter.cpp | 471 - .../ControlLib/AmdPowerTelemetryAdapter.h | 43 - .../ControlLib/AmdPowerTelemetryProvider.cpp | 94 - .../ControlLib/AmdPowerTelemetryProvider.h | 30 - IntelPresentMon/ControlLib/ControlLib.vcxproj | 51 +- .../ControlLib/ControlLib.vcxproj.filters | 117 +- IntelPresentMon/ControlLib/CpuTelemetry.cpp | 138 - IntelPresentMon/ControlLib/CpuTelemetry.h | 39 - IntelPresentMon/ControlLib/CpuTelemetryInfo.h | 28 - .../ControlLib/DeviceIdAllocator.h | 24 - .../ControlLib/IgclErrorCodeProvider.h | 12 - .../ControlLib/IgclErrorCodeProvider_old.cpp | 21 - .../ControlLib/IntelPowerTelemetryAdapter.h | 104 - .../IntelPowerTelemetryAdapter_old.cpp | 967 -- .../ControlLib/IntelPowerTelemetryProvider.h | 31 - .../IntelPowerTelemetryProvider_old.cpp | 99 - IntelPresentMon/ControlLib/Logging.h | 2 +- IntelPresentMon/ControlLib/MetricUse.h | 56 - .../NvidiaPowerTelemetryAdapter.cpp | 209 - .../ControlLib/NvidiaPowerTelemetryAdapter.h | 36 - .../NvidiaPowerTelemetryProvider.cpp | 111 - .../ControlLib/NvidiaPowerTelemetryProvider.h | 30 - .../ControlLib/PowerTelemetryAdapter.cpp | 45 - .../ControlLib/PowerTelemetryAdapter.h | 40 - .../ControlLib/PowerTelemetryProvider.h | 20 - .../PowerTelemetryProviderFactory.cpp | 19 - .../PowerTelemetryProviderFactory.h | 16 - .../ControlLib/PresentMonPowerTelemetry.h | 131 - .../ControlLib/SignatureComparison.cpp | 23 - .../ControlLib/SignatureComparison.h | 12 - .../ControlLib/TelemetryCoordinator.cpp | 110 + .../ControlLib/TelemetryCoordinator.h | 25 +- .../ControlLib/TelemetryDeviceFingerprint.h | 2 +- IntelPresentMon/ControlLib/WmiCpu.cpp | 144 - IntelPresentMon/ControlLib/WmiCpu.h | 33 - .../ControlLib/{ => adl}/Adl2Wrapper.cpp | 8 +- .../ControlLib/{ => adl}/Adl2Wrapper.h | 10 +- .../ControlLib/adl/AmdTelemetryProvider.cpp | 56 +- .../ControlLib/adl/AmdTelemetryProvider.h | 4 +- .../ControlLib/{ => adl}/adl_defines.h | 2 +- .../ControlLib/{ => adl}/adl_sdk.h | 2 +- .../ControlLib/{ => adl}/adl_structures.h | 2 +- .../ControlLib/cApiWrapper_old.cpp | 5784 ----------- .../ControlLib/igcl/IgclErrorCodeProvider.cpp | 2 +- .../ControlLib/igcl/IgclErrorCodeProvider.h | 2 +- IntelPresentMon/ControlLib/igcl_api.h | 8976 ----------------- .../nvapi/NvapiTelemetryProvider.cpp | 28 +- .../ControlLib/nvapi/NvapiTelemetryProvider.h | 6 +- .../ControlLib/{ => nvapi}/NvapiWrapper.cpp | 23 +- .../ControlLib/{ => nvapi}/NvapiWrapper.h | 20 +- .../ControlLib/{ => nvapi}/nvapi.h | 2 +- .../{ => nvapi}/nvapi_interface_table.h | 2 +- .../ControlLib/nvml/NvmlTelemetryProvider.cpp | 16 +- .../ControlLib/nvml/NvmlTelemetryProvider.h | 4 +- .../ControlLib/{ => nvml}/NvmlWrapper.cpp | 44 +- .../ControlLib/{ => nvml}/NvmlWrapper.h | 15 +- IntelPresentMon/ControlLib/{ => nvml}/nvml.h | 0 .../Interprocess/Interprocess.vcxproj | 5 +- .../Interprocess/Interprocess.vcxproj.filters | 11 +- .../Interprocess/source/Interprocess.h | 6 +- .../source/IntrospectionCapsLookup.h | 91 - .../source/IntrospectionPopulators.cpp | 10 +- .../source/MetricCapabilitiesShim.cpp | 124 - .../source/MetricCapabilitiesShim.h | 10 - .../PresentMonService/LogSetup.cpp | 6 +- IntelPresentMon/PresentMonService/MetricUse.h | 61 +- .../PresentMonService/PMMainThread.cpp | 4 + .../PowerTelemetryContainer.cpp | 51 - .../PowerTelemetryContainer.h | 18 - .../PresentMonService/PresentMon.cpp | 3 +- .../PresentMonService/PresentMon.h | 12 +- .../PresentMonService.vcxproj | 2 - .../PresentMonService.vcxproj.filters | 2 - .../PresentMonService/PresentMonSession.cpp | 33 +- .../PresentMonService/PresentMonSession.h | 15 +- .../acts/EnumerateAdapters.h | 12 +- 77 files changed, 372 insertions(+), 18447 deletions(-) delete mode 100644 IntelPresentMon/ControlLib/AmdPowerTelemetryAdapter.cpp delete mode 100644 IntelPresentMon/ControlLib/AmdPowerTelemetryAdapter.h delete mode 100644 IntelPresentMon/ControlLib/AmdPowerTelemetryProvider.cpp delete mode 100644 IntelPresentMon/ControlLib/AmdPowerTelemetryProvider.h delete mode 100644 IntelPresentMon/ControlLib/CpuTelemetry.cpp delete mode 100644 IntelPresentMon/ControlLib/CpuTelemetry.h delete mode 100644 IntelPresentMon/ControlLib/CpuTelemetryInfo.h delete mode 100644 IntelPresentMon/ControlLib/DeviceIdAllocator.h delete mode 100644 IntelPresentMon/ControlLib/IgclErrorCodeProvider.h delete mode 100644 IntelPresentMon/ControlLib/IgclErrorCodeProvider_old.cpp delete mode 100644 IntelPresentMon/ControlLib/IntelPowerTelemetryAdapter.h delete mode 100644 IntelPresentMon/ControlLib/IntelPowerTelemetryAdapter_old.cpp delete mode 100644 IntelPresentMon/ControlLib/IntelPowerTelemetryProvider.h delete mode 100644 IntelPresentMon/ControlLib/IntelPowerTelemetryProvider_old.cpp delete mode 100644 IntelPresentMon/ControlLib/MetricUse.h delete mode 100644 IntelPresentMon/ControlLib/NvidiaPowerTelemetryAdapter.cpp delete mode 100644 IntelPresentMon/ControlLib/NvidiaPowerTelemetryAdapter.h delete mode 100644 IntelPresentMon/ControlLib/NvidiaPowerTelemetryProvider.cpp delete mode 100644 IntelPresentMon/ControlLib/NvidiaPowerTelemetryProvider.h delete mode 100644 IntelPresentMon/ControlLib/PowerTelemetryAdapter.cpp delete mode 100644 IntelPresentMon/ControlLib/PowerTelemetryAdapter.h delete mode 100644 IntelPresentMon/ControlLib/PowerTelemetryProvider.h delete mode 100644 IntelPresentMon/ControlLib/PowerTelemetryProviderFactory.cpp delete mode 100644 IntelPresentMon/ControlLib/PowerTelemetryProviderFactory.h delete mode 100644 IntelPresentMon/ControlLib/PresentMonPowerTelemetry.h delete mode 100644 IntelPresentMon/ControlLib/SignatureComparison.cpp delete mode 100644 IntelPresentMon/ControlLib/SignatureComparison.h delete mode 100644 IntelPresentMon/ControlLib/WmiCpu.cpp delete mode 100644 IntelPresentMon/ControlLib/WmiCpu.h rename IntelPresentMon/ControlLib/{ => adl}/Adl2Wrapper.cpp (92%) rename IntelPresentMon/ControlLib/{ => adl}/Adl2Wrapper.h (97%) rename IntelPresentMon/ControlLib/{ => adl}/adl_defines.h (99%) rename IntelPresentMon/ControlLib/{ => adl}/adl_sdk.h (99%) rename IntelPresentMon/ControlLib/{ => adl}/adl_structures.h (99%) delete mode 100644 IntelPresentMon/ControlLib/cApiWrapper_old.cpp delete mode 100644 IntelPresentMon/ControlLib/igcl_api.h rename IntelPresentMon/ControlLib/{ => nvapi}/NvapiWrapper.cpp (83%) rename IntelPresentMon/ControlLib/{ => nvapi}/NvapiWrapper.h (87%) rename IntelPresentMon/ControlLib/{ => nvapi}/nvapi.h (99%) rename IntelPresentMon/ControlLib/{ => nvapi}/nvapi_interface_table.h (99%) rename IntelPresentMon/ControlLib/{ => nvml}/NvmlWrapper.cpp (56%) rename IntelPresentMon/ControlLib/{ => nvml}/NvmlWrapper.h (88%) rename IntelPresentMon/ControlLib/{ => nvml}/nvml.h (100%) delete mode 100644 IntelPresentMon/Interprocess/source/IntrospectionCapsLookup.h delete mode 100644 IntelPresentMon/Interprocess/source/MetricCapabilitiesShim.cpp delete mode 100644 IntelPresentMon/Interprocess/source/MetricCapabilitiesShim.h delete mode 100644 IntelPresentMon/PresentMonService/PowerTelemetryContainer.cpp delete mode 100644 IntelPresentMon/PresentMonService/PowerTelemetryContainer.h diff --git a/IntelPresentMon/CommonUtilities/ref/gen/GeneratedReflection.h b/IntelPresentMon/CommonUtilities/ref/gen/GeneratedReflection.h index ea1c2a94..da011329 100644 --- a/IntelPresentMon/CommonUtilities/ref/gen/GeneratedReflection.h +++ b/IntelPresentMon/CommonUtilities/ref/gen/GeneratedReflection.h @@ -10,7 +10,7 @@ #include "../GeneratedReflectionHelpers.h" // target includes -#include +#include "../../../../IntelPresentMon/ControlLib/igcl/igcl_api.h" namespace pmon::util::ref::gen { diff --git a/IntelPresentMon/ControlLib/AmdPowerTelemetryAdapter.cpp b/IntelPresentMon/ControlLib/AmdPowerTelemetryAdapter.cpp deleted file mode 100644 index 8521cae0..00000000 --- a/IntelPresentMon/ControlLib/AmdPowerTelemetryAdapter.cpp +++ /dev/null @@ -1,471 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#include "AmdPowerTelemetryAdapter.h" -#include "Logging.h" - -#include "../CommonUtilities/log/GlogShim.h" - -#define MAX_OD5_THERMAL_DEVICES 5; - -namespace pwr::amd { -AmdCheckerToken chk; - -AmdResultGrabber::AmdResultGrabber(int result, - std::source_location loc) noexcept - : result_(result), loc_(loc) {} -int operator>>(AmdResultGrabber g, AmdCheckerToken) noexcept { - if (g.result_ != ADL_OK) { - try { - LOG(INFO) << "Failed Telemetry Query: " << g.loc_.file_name() << " " - << g.loc_.line() << " " << g.result_; - } - catch (...) {} - } - return g.result_; -} - -AmdPowerTelemetryAdapter::AmdPowerTelemetryAdapter( - uint32_t deviceId, const Adl2Wrapper* adl2_wrapper, std::string adl_adapter_name, - int adl_adapter_index, int overdrive_version) - : PowerTelemetryAdapter(deviceId), - adl2_(adl2_wrapper), - name_(std::move(adl_adapter_name)), - adl_adapter_index_(adl_adapter_index), - overdrive_version_(overdrive_version) {} - -bool AmdPowerTelemetryAdapter::GetVideoMemoryInfo(uint64_t& gpu_mem_size, uint64_t& gpu_mem_max_bandwidth) const noexcept { - - bool success = false; - ADLMemoryInfoX4 memory_info; - - gpu_mem_size = 0; - gpu_mem_max_bandwidth = 0; - - auto result = adl2_->Adapter_MemoryInfoX4_Get(adl_adapter_index_, &memory_info) >> chk; - if (adl2_->Ok(result)) { - // iMemoryBandwidthX2 does not specify size but iMemoryBandwith - // returns megabytes per second. Assuming they are the same. - gpu_mem_max_bandwidth = static_cast(memory_info.iMemoryBandwidth) * 1000000; - // iMemorySize is the memory size in bytes - gpu_mem_size = static_cast(memory_info.iMemorySize); - success = true; - } - - return success; -} - - -bool AmdPowerTelemetryAdapter::GetSustainedPowerLimit(double& sustainedPowerLimit) const noexcept { - sustainedPowerLimit = 0.f; - if (overdrive_version_ == 5) { - int power_control_supported = 0; - int result = adl2_->Overdrive5_PowerControl_Caps( - adl_adapter_index_, &power_control_supported) >> chk; - if (adl2_->Ok(result)) { - if (power_control_supported) { - int power_control_current = 0; - int power_control_default = 0; - result = adl2_->Overdrive5_PowerControl_Get(adl_adapter_index_, - &power_control_current, &power_control_default) >> chk; - if (adl2_->Ok(result)) { - // Not sure on return type, assuming watts - sustainedPowerLimit = (double)power_control_current; - return true; - } - } - } - } else if (overdrive_version_ == 6) { - int power_control_supported = 0; - int result = adl2_->Overdrive6_PowerControl_Caps( - adl_adapter_index_, &power_control_supported) >> chk; - if (adl2_->Ok(result)) { - if (power_control_supported) { - int power_control_current = 0; - int power_control_default = 0; - result = adl2_->Overdrive6_PowerControl_Get(adl_adapter_index_, - &power_control_current, &power_control_default) >> chk; - if (adl2_->Ok(result)) { - sustainedPowerLimit = (double)power_control_current; - return true; - } - } - } - } - - return false; -} - -uint64_t AmdPowerTelemetryAdapter::GetDedicatedVideoMemory() const noexcept { - uint64_t video_mem_size = 0; - uint64_t video_max_bandwidth = 0; - GetVideoMemoryInfo(video_mem_size, video_max_bandwidth); - return video_mem_size; -} - -uint64_t AmdPowerTelemetryAdapter::GetVideoMemoryMaxBandwidth() const noexcept { - uint64_t video_mem_size = 0; - uint64_t video_max_bandwidth = 0; - - GetVideoMemoryInfo(video_mem_size, video_max_bandwidth); - return video_max_bandwidth; -} - -double AmdPowerTelemetryAdapter::GetSustainedPowerLimit() const noexcept { - double sustainedPowerLimit = 0.f; - GetSustainedPowerLimit(sustainedPowerLimit); - return sustainedPowerLimit; -} - -PresentMonPowerTelemetryInfo AmdPowerTelemetryAdapter::Sample() noexcept { - LARGE_INTEGER qpc; - QueryPerformanceCounter(&qpc); - - PresentMonPowerTelemetryInfo info{ - .qpc = (uint64_t)qpc.QuadPart, - }; - - // Sample metrics based on supported overdrive version - bool sample_return = false; - if (overdrive_version_ == 5) { - sample_return = Overdrive5Sample(info); - } else if (overdrive_version_ == 6) { - sample_return = Overdrive6Sample(info); - } else if (overdrive_version_ == 7) { - sample_return = Overdrive7Sample(info); - } else { - sample_return = Overdrive8Sample(info); - } - - // Next sample telemery data that is common. Starting with VRAM usage - { - int vram_usage = 0; - auto result = - adl2_->Adapter_VRAMUsage_Get(adl_adapter_index_, &vram_usage) >> chk; - // ADL Adapter_VRAMUsage_Get returns VRAM memory usage in MB - if (adl2_->Ok(result)) { - info.gpu_mem_used_b = static_cast(vram_usage) * 1000000; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_mem_used); - } - } - - // Next sample memory usage - { - if (GetVideoMemoryInfo(info.gpu_mem_total_size_b, info.gpu_mem_max_bandwidth_bps)){ - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_mem_max_bandwidth); - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_mem_size); - } - } - - (void)sample_return; - return info; -} - -bool AmdPowerTelemetryAdapter::Overdrive5Sample( - PresentMonPowerTelemetryInfo& info) noexcept { - // gpu temperature and fan speed - { - int result = 0; - ADLThermalControllerInfo thermals = {.iSize = - sizeof(ADLThermalControllerInfo)}; - // Call ADL_Overdrive5_ThermalDevices_Enum(). This is an interesting one as - // the ADL specification states to "Set to 0" for the - // iThermalControllerIndex but sample pieces of code in the SDK perform loop - // over this call increasing the index until ADL_WARNING_NO_DATA is - // returned. For now, follow the sample code and loop up to 5. We - // will report the LAST successful enumeration for now. - // TODO (megalvan) test this code out to see if 0 is the correct - // value to send OR if we are supposed to iterate. - for (int thermal_controller_index = 0; thermal_controller_index < 10; - thermal_controller_index++) { - result = - adl2_->Overdrive5_ThermalDevices_Enum( - adl_adapter_index_, thermal_controller_index, &thermals) >> - chk; - if (adl2_->Ok(result)) { - if (thermals.iThermalDomain == ADL_DL_THERMAL_DOMAIN_GPU) { - ADLTemperature temp = {.iSize = sizeof(ADLTemperature)}; - result = adl2_->Overdrive5_Temperature_Get( - adl_adapter_index_, thermal_controller_index, &temp) >> - chk; - if (adl2_->Ok(result)) { - // Temperature is returned in millidegrees Celsius - info.gpu_temperature_c = (double)temp.iTemperature / 1000.; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_temperature); - } - ADLFanSpeedInfo fan_speed_info = {.iSize = sizeof(ADLFanSpeedInfo)}; - result = adl2_->Overdrive5_FanSpeedInfo_Get(adl_adapter_index_, - thermal_controller_index, - &fan_speed_info) >> - chk; - if (adl2_->Ok(result)) { - // Fan speed can be reported as RPMs or in percent. We only - // support RPMs. Probably should report both and let user - // select which they want. - if ((fan_speed_info.iFlags & ADL_DL_FANCTRL_SUPPORTS_RPM_READ) == - ADL_DL_FANCTRL_SUPPORTS_RPM_READ) { - ADLFanSpeedValue fan_speed_value = { - .iSize = sizeof(ADLFanSpeedValue), - .iSpeedType = ADL_DL_FANCTRL_SPEED_TYPE_RPM}; - result = adl2_->Overdrive5_FanSpeed_Get(adl_adapter_index_, - thermal_controller_index, - &fan_speed_value) >> - chk; - if (adl2_->Ok(result)) { - info.fan_speed_rpm[thermal_controller_index] = - (double)fan_speed_value.iFanSpeed; - // TODO -> create function to fix this!! - SetTelemetryCapBit(GpuTelemetryCapBits::fan_speed_1); - } - } - } - } - } - } - } - - // GPU, VRAM clock frequencies and GPU voltage - { - ADLPMActivity activity = {.iSize = sizeof(ADLPMActivity)}; - int result = - adl2_->Overdrive5_CurrentActivity_Get(adl_adapter_index_, &activity) >> - chk; - if (adl2_->Ok(result)) { - info.gpu_utilization = (double)activity.iActivityPercent; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_utilization); - // It appears iEngineClock and iMemory clock come back as 10 Khz. - // This is what the Overdrive6 API reports back and appears to be - // confirmed from the Overdrive sample applications. - info.gpu_frequency_mhz = (double)activity.iEngineClock / 100; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_frequency); - info.vram_frequency_mhz = (double)activity.iMemoryClock / 100; - SetTelemetryCapBit(GpuTelemetryCapBits::vram_frequency); - // Overdrive sample application treats this as volts. - info.gpu_voltage_v = (double)activity.iVddc; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_voltage); - } - } - - // Current Sustained Power Control limit - { - if (GetSustainedPowerLimit(info.gpu_sustained_power_limit_w)) { - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_sustained_power_limit); - } - } - - // How does one make sure the OverdriveN functions are available?? - { - ADLODNPerformanceStatus performance_status = {}; - int result = adl2_->OverdriveN_PerformanceStatus_Get(adl_adapter_index_, - &performance_status) >> - chk; - if (adl2_->Ok(result)) { - // Overdrive sample application treats this as volts. - info.gpu_voltage_v = (double)performance_status.iVDDC; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_voltage); - } - } - - return true; -} - -bool AmdPowerTelemetryAdapter::Overdrive6Sample( - PresentMonPowerTelemetryInfo& info) noexcept { - // gpu temperature and fan speed - { - ADLOD6ThermalControllerCaps thermals = {}; - int result = adl2_->Overdrive6_ThermalController_Caps(adl_adapter_index_, - &thermals) >> - chk; - if (adl2_->Ok(result)) { - // As with overdrive 5 we must check if reading of RPMs is allowed by the - // gpu. - if ((thermals.iCapabilities & ADL_OD6_TCCAPS_FANSPEED_RPM_READ) == - ADL_OD6_TCCAPS_FANSPEED_RPM_READ) { - ADLOD6FanSpeedInfo fan_speed_info = {}; - result = adl2_->Overdrive6_FanSpeed_Get(adl_adapter_index_, - &fan_speed_info) >> - chk; - if (adl2_->Ok(result)) { - if ((fan_speed_info.iSpeedType & ADL_OD6_FANSPEED_TYPE_RPM) == - ADL_OD6_FANSPEED_TYPE_RPM) { - info.fan_speed_rpm[0] = (double)fan_speed_info.iFanSpeedRPM; - SetTelemetryCapBit(GpuTelemetryCapBits::fan_speed_1); - } - } - } - - // Make sure thermal controller exists on the gpu - if ((thermals.iCapabilities & ADL_OD6_TCCAPS_THERMAL_CONTROLLER) == - ADL_OD6_TCCAPS_THERMAL_CONTROLLER) { - int temp = 0; - result = - adl2_->Overdrive6_Temperature_Get(adl_adapter_index_, &temp) >> chk; - if (adl2_->Ok(result)) { - // Temperature is returned in millidegrees Celsius - info.gpu_temperature_c = (double)temp / 1000.; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_temperature); - } - } - } - } - - // gpu and vram frequencies, as well as gpu utilization - { - ADLOD6CurrentStatus currentStatus = {}; - int result = adl2_->Overdrive6_CurrentStatus_Get(adl_adapter_index_, - ¤tStatus) >> - chk; - if (adl2_->Ok(result)) { - // iEngineClock and iMemory clock are returned as 10 Khz - info.gpu_frequency_mhz = - static_cast(currentStatus.iEngineClock) / 100.; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_frequency); - info.vram_frequency_mhz = - static_cast(currentStatus.iMemoryClock) / 100.; - SetTelemetryCapBit(GpuTelemetryCapBits::vram_frequency); - ADLOD6Capabilities caps = {}; - result = - adl2_->Overdrive6_Capabilities_Get(adl_adapter_index_, &caps) >> chk; - if (adl2_->Ok(result)) { - if ((caps.iCapabilities & ADL_OD6_CAPABILITY_GPU_ACTIVITY_MONITOR) == - ADL_OD6_CAPABILITY_GPU_ACTIVITY_MONITOR) { - info.gpu_utilization = (double)currentStatus.iActivityPercent; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_utilization); - } - } - } - } - - // gpu power - { - int current_power_w = 0; - int result = adl2_->Overdrive6_CurrentPower_Get(adl_adapter_index_, 0, - ¤t_power_w) >> - chk; - if (adl2_->Ok(result)) { - // The returned int contains the current power in Watts with 8 - // fractional bits - info.gpu_power_w = (double)(current_power_w >> 8); - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_power); - } - } - - // sustained power control limit - { - if (GetSustainedPowerLimit(info.gpu_sustained_power_limit_w)) { - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_sustained_power_limit); - } - } - - return true; -} - -bool AmdPowerTelemetryAdapter::Overdrive7Sample( - PresentMonPowerTelemetryInfo& info) noexcept { - - ADLODNCapabilitiesX2 od_caps = {}; - int result = - adl2_->OverdriveN_CapabilitiesX2_Get(adl_adapter_index_, &od_caps) >> - chk; - if (adl2_->Ok(result)) { - ADLODNPerformanceStatus od_perf_status = {}; - result = adl2_->OverdriveN_PerformanceStatus_Get(adl_adapter_index_, - &od_perf_status) >> - chk; - if (adl2_->Ok(result)) { - // iEngineClock and iMemory clock are returned as 10 Khz - info.gpu_frequency_mhz = (double)od_perf_status.iCoreClock / 100.; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_frequency); - info.vram_frequency_mhz = (double)od_perf_status.iMemoryClock / 100.; - SetTelemetryCapBit(GpuTelemetryCapBits::vram_frequency); - info.gpu_voltage_v = (double)od_perf_status.iVDDC / 1000.; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_voltage); - info.gpu_utilization = (double)od_perf_status.iGPUActivityPercent; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_utilization); - } - int temperature = 0; - result = adl2_->OverdriveN_Temperature_Get(adl_adapter_index_, 1, - &temperature) >> - chk; - if (adl2_->Ok(result)) { - // Temperature is returned in millidegrees Celsius - info.gpu_temperature_c = (double)temperature / 1000.; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_temperature); - } - ADLODNFanControl od_fan_control = {}; - result = - adl2_->OverdriveN_FanControl_Get(adl_adapter_index_, &od_fan_control) >> chk; - if (adl2_->Ok(result)) { - info.fan_speed_rpm[0] = (double)od_fan_control.iCurrentFanSpeed; - SetTelemetryCapBit(GpuTelemetryCapBits::fan_speed_0); - } - } - - // gpu power - { - int current_power_w = 0; - int result = adl2_->Overdrive6_CurrentPower_Get(adl_adapter_index_, 0, - ¤t_power_w) >> - chk; - if (adl2_->Ok(result)) { - // The returned int contains the current power in Watts with 8 - // fractional bits - info.gpu_power_w = (double)(current_power_w >> 8); - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_power); - } - } - - return true; -} - -bool AmdPowerTelemetryAdapter::Overdrive8Sample( - PresentMonPowerTelemetryInfo& info) noexcept { - ADLPMLogDataOutput data_output = {}; - if (adl2_->Ok(adl2_->New_QueryPMLogData_Get(adl_adapter_index_, - &data_output))) { - if (data_output.sensors[PMLOG_CLK_GFXCLK].supported) { - info.gpu_frequency_mhz = (double)data_output.sensors[PMLOG_CLK_GFXCLK].value; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_frequency); - } - if (data_output.sensors[PMLOG_CLK_MEMCLK].supported) { - info.vram_frequency_mhz = (double)data_output.sensors[PMLOG_CLK_MEMCLK].value; - SetTelemetryCapBit(GpuTelemetryCapBits::vram_frequency); - } - if (data_output.sensors[PMLOG_FAN_RPM].supported) { - info.fan_speed_rpm[0] = (double)data_output.sensors[PMLOG_FAN_RPM].value; - SetTelemetryCapBit(GpuTelemetryCapBits::fan_speed_0); - } - if (data_output.sensors[PMLOG_TEMPERATURE_EDGE].supported) { - info.gpu_temperature_c = - (double)data_output.sensors[PMLOG_TEMPERATURE_EDGE].value; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_temperature); - } - if (data_output.sensors[PMLOG_INFO_ACTIVITY_GFX].supported) { - info.gpu_utilization = - (double)data_output.sensors[PMLOG_INFO_ACTIVITY_GFX].value; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_utilization); - } - if (data_output.sensors[PMLOG_GFX_VOLTAGE].supported) { - info.gpu_voltage_v = - (double)data_output.sensors[PMLOG_GFX_VOLTAGE].value / 1000.; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_voltage); - } - if (data_output.sensors[PMLOG_ASIC_POWER].supported) { - info.gpu_power_w = (double)data_output.sensors[PMLOG_ASIC_POWER].value; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_power); - } - return true; - } else { - return false; - } -} - -PM_DEVICE_VENDOR AmdPowerTelemetryAdapter::GetVendor() const noexcept { - return PM_DEVICE_VENDOR::PM_DEVICE_VENDOR_AMD; -} - -std::string AmdPowerTelemetryAdapter::GetName() const noexcept { - return name_; -} - -} // namespace pwr::amd diff --git a/IntelPresentMon/ControlLib/AmdPowerTelemetryAdapter.h b/IntelPresentMon/ControlLib/AmdPowerTelemetryAdapter.h deleted file mode 100644 index 45361e5e..00000000 --- a/IntelPresentMon/ControlLib/AmdPowerTelemetryAdapter.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#pragma once -#include -#include "PowerTelemetryAdapter.h" -#include "Adl2Wrapper.h" - -namespace pwr::amd { -struct AmdCheckerToken {}; -extern AmdCheckerToken chk; -struct AmdResultGrabber { - AmdResultGrabber(int result, - std::source_location = std::source_location::current()) noexcept; - int result_; - std::source_location loc_; -}; -int operator>>(AmdResultGrabber, AmdCheckerToken) noexcept; - -class AmdPowerTelemetryAdapter : public PowerTelemetryAdapter { - public: - AmdPowerTelemetryAdapter(uint32_t deviceId, const Adl2Wrapper* adl_wrapper, std::string adl_adapter_name, - int adl_adapter_index, int overdrive_version); - PresentMonPowerTelemetryInfo Sample() noexcept override; - PM_DEVICE_VENDOR GetVendor() const noexcept override; - std::string GetName() const noexcept override; - uint64_t GetDedicatedVideoMemory() const noexcept override; - uint64_t GetVideoMemoryMaxBandwidth() const noexcept override; - double GetSustainedPowerLimit() const noexcept override; - - private: - bool Overdrive5Sample(PresentMonPowerTelemetryInfo& info) noexcept; - bool Overdrive6Sample(PresentMonPowerTelemetryInfo& info) noexcept; - bool Overdrive7Sample(PresentMonPowerTelemetryInfo& info) noexcept; - bool Overdrive8Sample(PresentMonPowerTelemetryInfo& info) noexcept; - bool GetVideoMemoryInfo(uint64_t& gpu_mem_size, uint64_t& gpu_mem_max_bandwidth) const noexcept; - bool GetSustainedPowerLimit(double& sustainedPowerLimit) const noexcept; - - const Adl2Wrapper* adl2_; - int adl_adapter_index_ = 0; - int overdrive_version_ = 0; - std::string name_ = "Unknown Adapter Name"; -}; -} diff --git a/IntelPresentMon/ControlLib/AmdPowerTelemetryProvider.cpp b/IntelPresentMon/ControlLib/AmdPowerTelemetryProvider.cpp deleted file mode 100644 index 8df1b950..00000000 --- a/IntelPresentMon/ControlLib/AmdPowerTelemetryProvider.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#include -#include -#include "AmdPowerTelemetryProvider.h" -#include "AmdPowerTelemetryAdapter.h" -#include "Logging.h" - -#define AMDVENDORID (1002) - -namespace pwr::amd { - -AmdPowerTelemetryProvider::AmdPowerTelemetryProvider(DeviceIdAllocator& allocator) { - int count = 0; - if (!adl_.Ok(adl_.Adapter_NumberOfAdapters_Get(&count))) { - throw std::runtime_error{"Failed to get number of amd gpus"}; - } - // Resize the container to the actual count of adl adapter infos - adl_adapter_infos_.resize(count); - - // Get the adapter infos - int full_adapter_info_size = - (int)(adl_adapter_infos_.size() * sizeof(AdapterInfo)); - if (!adl_.Ok(adl_.Adapter_AdapterInfo_Get(adl_adapter_infos_.data(), - full_adapter_info_size))) { - throw std::runtime_error{"Failed to adapter infos for amd gpus"}; - } - - // Map of bus number to adapter string to track unique adapters - std::map adapters; - - for (auto& ai : adl_adapter_infos_) { - // Following the AMD example code for using Overdrive8 here. Instead of making - // a call to ADL2_Adapter_Active_Get the sample code checks the bus number. We - // are following this methodology as well because when making this call from - // the service ADL2_Adapter_Active_Get never returns an active adapter while - // the bus number is active and Overdrive caps report support. - if ((ai.iBusNumber > -1) && ai.iVendorID == AMDVENDORID) { - int overdrive_supported = 0; - int overdrive_enabled = 0; - int overdrive_version = 0; - // Again following the AMD Overdrive8 sample code. The code does not - // check for success on the Overdrive_Caps call. Instead just checks - // the supported overdrive version. - adl_.Overdrive_Caps(ai.iAdapterIndex, &overdrive_supported, - &overdrive_enabled, &overdrive_version); - - // If we don't get updated values for ANY of the passed in parameters - // bail out. - if ((overdrive_supported == 0) && (overdrive_enabled == 0) && - (overdrive_version == 0)) { - throw std::runtime_error{"Failed to get overdrive caps for amd gpus"}; - } - - // If it's not a version of overdrive we support, bail out. - if ((overdrive_version < 5) || (overdrive_version > 8)) { - throw std::runtime_error{ - std::format( - "Overdrive version is not supported. Version reported: {}", - overdrive_version) - .c_str()}; - } - - auto result = - adapters.insert(std::pair{ai.iBusNumber, ai.strAdapterName}); - if (result.second) { - try { - std::string adl_adapter_name = ai.strAdapterName; - adapter_ptrs_.push_back(std::make_shared( - allocator.Next(), &adl_, adl_adapter_name, ai.iAdapterIndex, overdrive_version)); - } catch (const std::exception& e) { - TELE_ERR(e.what()); - } catch (...) { - TELE_ERR("unknown error"); - } - } - } - } -} - -AmdPowerTelemetryProvider::~AmdPowerTelemetryProvider() { - adapter_ptrs_.clear(); -} - -const std::vector>& -AmdPowerTelemetryProvider::GetAdapters() noexcept { - return adapter_ptrs_; -} - -uint32_t AmdPowerTelemetryProvider::GetAdapterCount() const noexcept { - return (uint32_t)adapter_ptrs_.size(); -} - -} // namespace pwr::amd diff --git a/IntelPresentMon/ControlLib/AmdPowerTelemetryProvider.h b/IntelPresentMon/ControlLib/AmdPowerTelemetryProvider.h deleted file mode 100644 index c79fb500..00000000 --- a/IntelPresentMon/ControlLib/AmdPowerTelemetryProvider.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#pragma once -#define NOMINMAX -#include -#include -#include -#include -#include "PresentMonPowerTelemetry.h" -#include "PowerTelemetryProvider.h" -#include "Adl2Wrapper.h" -#include "DeviceIdAllocator.h" - -namespace pwr::amd { -class AmdPowerTelemetryProvider : public PowerTelemetryProvider { - public: - explicit AmdPowerTelemetryProvider(DeviceIdAllocator& allocator); - AmdPowerTelemetryProvider(const AmdPowerTelemetryProvider& t) = delete; - AmdPowerTelemetryProvider& operator=(const AmdPowerTelemetryProvider& t) = delete; - ~AmdPowerTelemetryProvider() override; - const std::vector>& - GetAdapters() noexcept override; - uint32_t GetAdapterCount() const noexcept override; - - private: - Adl2Wrapper adl_; - std::vector adl_adapter_infos_; - std::vector> adapter_ptrs_; -}; -} // namespace pwr::amd diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj b/IntelPresentMon/ControlLib/ControlLib.vcxproj index e3fe5ef6..a67a324a 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj @@ -107,70 +107,43 @@ - - - + + + + - - - - - - - + + + + - - - - - - - - + - - - - - - - + - - - - - + + - - - - - - - - - diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters index cdd7ce8e..62b6c898 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters @@ -19,28 +19,22 @@ - - Intel - - - Intel - - - Intel + + Amd - - Nvidia + + Amd - - Nvidia + + Amd - + Nvidia - + Nvidia - + Nvidia @@ -49,48 +43,23 @@ Nvidia - + Nvidia - - Nvidia - - - Nvidia - - + Nvidia - + Nvidia - - Amd - - - Amd - - + Amd Amd - - Intel - - - - - - - - - - Intel - @@ -98,71 +67,49 @@ Intel - - + + Intel + + + Intel + + + Nvidia + Wmi - + Nvidia Nvidia - - Nvidia - - - Nvidia - - + Nvidia - - Nvidia - - + Nvidia - - Intel - - - Intel - - - Intel - - - Intel - - - Amd - - - Amd - - + Amd Amd - - - - - Intel - Intel - - + + Intel + + + Intel + Wmi diff --git a/IntelPresentMon/ControlLib/CpuTelemetry.cpp b/IntelPresentMon/ControlLib/CpuTelemetry.cpp deleted file mode 100644 index 0700923a..00000000 --- a/IntelPresentMon/ControlLib/CpuTelemetry.cpp +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#include -#include "CpuTelemetry.h" -#include "../CommonUtilities/str/String.h" - -#include "../CommonUtilities/log/GlogShim.h" - - -namespace pwr::cpu { - using namespace pmon::util; - -std::string CpuTelemetry::GetCpuName() { - if (cpu_name_.size() == 0) { - std::wstring local_cpu_name{}; - if (ExecuteWQLProcessorNameQuery(local_cpu_name)) { - cpu_name_ = str::TrimWhitespace(str::ToNarrow(local_cpu_name)); - } else { - cpu_name_ = "UNKNOWN_CPU"; - } - } - - return cpu_name_; -} - -bool CpuTelemetry::ExecuteWQLProcessorNameQuery( - std::wstring& processor_name) { - struct ComHelper { - ComHelper() { - HRESULT result{CoInitializeEx(nullptr, COINIT_MULTITHREADED)}; - - if (FAILED(result)) { - throw std::runtime_error( - std::format("Failed CoInitializeEx. Result: {}", result).c_str()); - } - - result = CoInitializeSecurity( - nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_DEFAULT, - RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE, nullptr); - - if (FAILED(result)) { - CoUninitialize(); - throw std::runtime_error( - std::format("Failed CoInitializeSecurity. Result: {}", result) - .c_str()); - } - } - ComHelper(const ComHelper& t) = delete; - ComHelper& operator=(const ComHelper& t) = delete; - ~ComHelper() { CoUninitialize(); } - }; - - // Initialize to empty state - processor_name.clear(); - - try { - ComHelper com_helper; - - std::wstring query(L"SELECT Name FROM Win32_Processor"); - std::wstring server_name(L"ROOT\\CIMV2"); - std::wstring locale(L"MS_409"); - - Microsoft::WRL::ComPtr locator; - HRESULT result = - CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, - IID_IWbemLocator, (&locator)); - - if (FAILED(result)) { - LOG(INFO) << "Failed CoCreateInstance: " << result << std::endl; - return false; - } - - Microsoft::WRL::ComPtr services; - result = locator->ConnectServer(_bstr_t(server_name.c_str()), nullptr, - nullptr, _bstr_t(locale.c_str()), NULL, - nullptr, nullptr, &services); - - if (FAILED(result)) { - LOG(INFO) << "Failed ConnectServer: " << result << std::endl; - return false; - } - - result = - CoSetProxyBlanket(services.Get(), RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, - nullptr, RPC_C_AUTHN_LEVEL_CALL, - RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE); - - if (FAILED(result)) { - LOG(INFO) << "Failed CoSetProxyBlanket: " << result << std::endl; - return false; - } - - Microsoft::WRL::ComPtr enumerator; - result = services->ExecQuery( - bstr_t(L"WQL"), bstr_t(query.c_str()), - WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, nullptr, - &enumerator); - - if (FAILED(result)) { - LOG(INFO) << "Failed ExecQuery: " << result << std::endl; - return false; - } - - IWbemClassObject* ClassObject{}; - DWORD returned{}; - result = enumerator->Next(WBEM_INFINITE, 1, &ClassObject, &returned); - - if (FAILED(result) || returned == 0) { - LOG(INFO) << "Failed Next: " << result << std::endl; - return false; - } - - VARIANT variant{}; - result = ClassObject->Get(L"Name", 0, &variant, nullptr, nullptr); - if (FAILED(result)) { - LOG(INFO) << "Failed Name Get: " << result << std::endl; - return false; - } - - if (variant.vt == VT_BSTR) { - processor_name = variant.bstrVal; - } - - VariantClear(&variant); - ClassObject->Release(); - - return true; - - } catch (const std::runtime_error& e) { - LOG(INFO) << e.what() << std::endl; - return false; - } catch (...) { - LOG(INFO) << "Unknown COM Initialize Error" << std::endl; - return false; - } -} - -} \ No newline at end of file diff --git a/IntelPresentMon/ControlLib/CpuTelemetry.h b/IntelPresentMon/ControlLib/CpuTelemetry.h deleted file mode 100644 index dcee0bd3..00000000 --- a/IntelPresentMon/ControlLib/CpuTelemetry.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#pragma once - -#include -#include -#include -#include -#include -#include -#include "CpuTelemetryInfo.h" - -namespace pwr::cpu { - -class CpuTelemetry { - public: - virtual ~CpuTelemetry() = default; - virtual CpuTelemetryInfo Sample() noexcept = 0; - void SetTelemetryCapBit(CpuTelemetryCapBits telemetryCapBit) noexcept - { - cpuTelemetryCapBits_.set(static_cast(telemetryCapBit)); - } - std::bitset(CpuTelemetryCapBits::cpu_telemetry_count)> GetCpuTelemetryCapBits() - { - return cpuTelemetryCapBits_; - } - - std::string GetCpuName(); - double GetCpuPowerLimit() { return 0.; } - - private: - - bool ExecuteWQLProcessorNameQuery(std::wstring& processor_name); - - std::bitset(CpuTelemetryCapBits::cpu_telemetry_count)> - cpuTelemetryCapBits_{}; - std::string cpu_name_; -}; -} diff --git a/IntelPresentMon/ControlLib/CpuTelemetryInfo.h b/IntelPresentMon/ControlLib/CpuTelemetryInfo.h deleted file mode 100644 index 23c2fa47..00000000 --- a/IntelPresentMon/ControlLib/CpuTelemetryInfo.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#pragma once - -#include -#include - -struct CpuTelemetryInfo { - uint64_t qpc; - - double cpu_utilization; - double cpu_power_w; - double cpu_power_limit_w; - double cpu_temperature; - double cpu_frequency; -}; - -enum class CpuTelemetryCapBits { - cpu_utilization, - cpu_power, - cpu_power_limit, - cpu_temperature, - cpu_frequency, - cpu_core_utility, - cpu_telemetry_count -}; - -using CpuTelemetryBitset = std::bitset(CpuTelemetryCapBits::cpu_telemetry_count)>; \ No newline at end of file diff --git a/IntelPresentMon/ControlLib/DeviceIdAllocator.h b/IntelPresentMon/ControlLib/DeviceIdAllocator.h deleted file mode 100644 index 1e1e7f48..00000000 --- a/IntelPresentMon/ControlLib/DeviceIdAllocator.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2024 Intel Corporation -// SPDX-License-Identifier: MIT -#pragma once - -#include -#include - -namespace pwr -{ - class DeviceIdAllocator - { - public: - explicit DeviceIdAllocator(uint32_t startId = 1) noexcept - : nextId_{ startId } {} - - uint32_t Next() noexcept - { - return nextId_.fetch_add(1, std::memory_order_relaxed); - } - - private: - std::atomic nextId_; - }; -} diff --git a/IntelPresentMon/ControlLib/IgclErrorCodeProvider.h b/IntelPresentMon/ControlLib/IgclErrorCodeProvider.h deleted file mode 100644 index 2e2eb74e..00000000 --- a/IntelPresentMon/ControlLib/IgclErrorCodeProvider.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "../CommonUtilities/log/IErrorCodeProvider.h" - -namespace pwr::intel -{ - class IgclErrorCodeProvider : public pmon::util::log::IErrorCodeProvider - { - public: - std::type_index GetTargetType() const override; - pmon::util::log::IErrorCodeResolver::Strings Resolve(const pmon::util::log::ErrorCode&) const override; - }; -} \ No newline at end of file diff --git a/IntelPresentMon/ControlLib/IgclErrorCodeProvider_old.cpp b/IntelPresentMon/ControlLib/IgclErrorCodeProvider_old.cpp deleted file mode 100644 index bc27b09d..00000000 --- a/IntelPresentMon/ControlLib/IgclErrorCodeProvider_old.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "IgclErrorCodeProvider.h" -#include "../CommonUtilities/log/ErrorCode.h" -#include "../CommonUtilities/ref/GeneratedReflection.h" -#include "igcl_api.h" - -using namespace pmon::util; - -namespace pwr::intel -{ - std::type_index IgclErrorCodeProvider::GetTargetType() const - { - return typeid(ctl_result_t); - } - log::IErrorCodeResolver::Strings IgclErrorCodeProvider::Resolve(const pmon::util::log::ErrorCode& ec) const - { - return log::IErrorCodeResolver::Strings{ - .type = "ctl_result_t", - .symbol = ref::DumpGenerated((ctl_result_t)*ec.AsSigned()), - }; - } -} \ No newline at end of file diff --git a/IntelPresentMon/ControlLib/IntelPowerTelemetryAdapter.h b/IntelPresentMon/ControlLib/IntelPowerTelemetryAdapter.h deleted file mode 100644 index 0e9e4982..00000000 --- a/IntelPresentMon/ControlLib/IntelPowerTelemetryAdapter.h +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#pragma once -#define NOMINMAX -#include -#include "igcl_api.h" -#include "PowerTelemetryAdapter.h" -#include - -namespace pwr::intel -{ - class IntelPowerTelemetryAdapter : public PowerTelemetryAdapter - { - public: - IntelPowerTelemetryAdapter(uint32_t deviceId, ctl_device_adapter_handle_t handle); - PresentMonPowerTelemetryInfo Sample() noexcept override; - PM_DEVICE_VENDOR GetVendor() const noexcept override; - std::string GetName() const noexcept override; - uint64_t GetDedicatedVideoMemory() const noexcept override; - uint64_t GetVideoMemoryMaxBandwidth() const noexcept override; - double GetSustainedPowerLimit() const noexcept override; - uint64_t GetAdapterId() const noexcept override; - - // types - class NonGraphicsDeviceException : public std::exception {}; - - private: - // functions - bool GatherSampleData(ctl_power_telemetry_t& currentSample, - ctl_mem_state_t& memory_state, - bool has_memory_state, - ctl_mem_bandwidth_t& memory_bandwidth, - bool has_memory_bandwidth, - std::optional gpu_sustained_power_limit_mw, - uint64_t qpc, - PresentMonPowerTelemetryInfo& sample); - - ctl_result_t EnumerateMemoryModules(); - - ctl_result_t GetTimeDelta(const ctl_power_telemetry_t& power_telemetry); - - // TODO: meld these into the sample function - ctl_result_t GetGPUPowerTelemetryData( - const ctl_power_telemetry_t& power_telemetry, - PresentMonPowerTelemetryInfo& pm_gpu_power_telemetry_info); - ctl_result_t GetVramPowerTelemetryData( - const ctl_power_telemetry_t& power_telemetry, - PresentMonPowerTelemetryInfo& pm_gpu_power_telemetry_info); - ctl_result_t GetFanPowerTelemetryData( - const ctl_power_telemetry_t& power_telemetry, - PresentMonPowerTelemetryInfo& pm_gpu_power_telemetry_info); - ctl_result_t GetPsuPowerTelemetryData( - const ctl_power_telemetry_t& power_telemetry, - PresentMonPowerTelemetryInfo& pm_gpu_power_telemetry_info); - - void GetMemStateTelemetryData( - const ctl_mem_state_t& mem_state, - PresentMonPowerTelemetryInfo& pm_gpu_power_telemetry_info); - void GetMemBandwidthData( - const ctl_mem_bandwidth_t& mem_bandwidth, - PresentMonPowerTelemetryInfo& pm_gpu_power_telemetry_info); - - ctl_result_t SaveTelemetry( - const ctl_power_telemetry_t& power_telemetry); - - // TODO: put these as part of the telemetry data object - ctl_result_t GetInstantaneousPowerTelemetryItem( - const ctl_oc_telemetry_item_t& telemetry_item, - double& pm_telemetry_value, - GpuTelemetryCapBits telemetry_cap_bit); - ctl_result_t GetPowerTelemetryItemUsagePercent( - const ctl_oc_telemetry_item_t& current_telemetry_item, - const ctl_oc_telemetry_item_t& previous_telemetry_item, - double& pm_telemetry_value, - GpuTelemetryCapBits telemetry_cap_bit); - ctl_result_t GetPowerTelemetryItemUsage( - const ctl_oc_telemetry_item_t& current_telemetry_item, - const ctl_oc_telemetry_item_t& previous_telemetry_item, - double& pm_telemetry_value, - GpuTelemetryCapBits telemetry_cap_bit); - // data - ctl_device_adapter_handle_t deviceHandle = nullptr; - LUID deviceLuid; // pointed to by a device_adapter_properties member, written to by igcl api - ctl_device_adapter_properties_t properties{}; - std::vector memoryModules; - std::vector powerDomains; - std::optional previousSample; - bool useNewBandwidthTelemetry = true; - double time_delta_ = 0.f; - // in V0 api readbandwidth occasionally returns what appears to be an invalid counter value - // this is a stopgap to cover for cases where IGCL is reporting bad data in V0 bandwidth telemetry - double gpu_mem_read_bw_cache_value_bps_ = 0.; - uint64_t gpu_mem_max_bw_cache_value_bps_ = 0; - // in V1 api vramEnergyCounter rolls over after hitting 1000.0 causing the current sample to be - // less than the previous sample. Working with IGCL to determine the correct behavior for roll - // over occasions - double gpu_mem_power_cache_value_w_ = 0; - // we have special handling for GPU current perf limitation on Alchemist - // workaround for lack of discoverablity of perf limitation availability - bool isAlchemist = false; - // populated on init, used to calculate fan % - std::vector maxFanSpeedsRpm_; - }; -} diff --git a/IntelPresentMon/ControlLib/IntelPowerTelemetryAdapter_old.cpp b/IntelPresentMon/ControlLib/IntelPowerTelemetryAdapter_old.cpp deleted file mode 100644 index 86061b1e..00000000 --- a/IntelPresentMon/ControlLib/IntelPowerTelemetryAdapter_old.cpp +++ /dev/null @@ -1,967 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#include "IntelPowerTelemetryAdapter.h" -#include "Logging.h" -#include "../CommonUtilities/Math.h" -#include "../CommonUtilities/ref/GeneratedReflection.h" -#include "../CommonUtilities/ref/StaticReflection.h" -#include -#include -#include - -using namespace pmon; -using namespace util; -namespace vi = std::views; -using v = log::V; - -namespace pwr::intel -{ - namespace { - GpuTelemetryCapBits GetFanSpeedTelemetryCapBit_( - uint32_t fan_index) { - switch (fan_index) { - case 0: - return GpuTelemetryCapBits::fan_speed_0; - case 1: - return GpuTelemetryCapBits::fan_speed_1; - case 2: - return GpuTelemetryCapBits::fan_speed_2; - case 3: - return GpuTelemetryCapBits::fan_speed_3; - case 4: - return GpuTelemetryCapBits::fan_speed_4; - default: - throw std::runtime_error{ "Invalid fan speed index" }; - } - } - GpuTelemetryCapBits GetPsuTelemetryCapBit_( - uint32_t psu_index) { - switch (psu_index) { - case 0: - return GpuTelemetryCapBits::psu_info_0; - case 1: - return GpuTelemetryCapBits::psu_info_1; - case 2: - return GpuTelemetryCapBits::psu_info_2; - case 3: - return GpuTelemetryCapBits::psu_info_3; - case 4: - return GpuTelemetryCapBits::psu_info_4; - default: - throw std::runtime_error{ "Invalid PSU index" }; - } - } - GpuTelemetryCapBits GetMaxFanSpeedTelemetryCapBit_( - uint32_t index) { - switch (index) { - case 0: - return GpuTelemetryCapBits::max_fan_speed_0; - case 1: - return GpuTelemetryCapBits::max_fan_speed_1; - case 2: - return GpuTelemetryCapBits::max_fan_speed_2; - case 3: - return GpuTelemetryCapBits::max_fan_speed_3; - case 4: - return GpuTelemetryCapBits::max_fan_speed_4; - default: - throw std::runtime_error{ "Invalid max fan speed index" }; - } - } - } - - // public interface functions - - IntelPowerTelemetryAdapter::IntelPowerTelemetryAdapter(uint32_t deviceId, ctl_device_adapter_handle_t handle) - : - PowerTelemetryAdapter(deviceId), - deviceHandle{ handle } - { - properties = { - .Size = sizeof(ctl_device_adapter_properties_t), - .pDeviceID = &deviceLuid, - .device_id_size = sizeof(deviceLuid), - }; - - if (auto result = ctlGetDeviceProperties(deviceHandle, &properties); - result != CTL_RESULT_SUCCESS) { - pmlog_error("ctlGetDeviceProperties failed").code(result) - .pmwatch(GetDeviceId()); - throw std::runtime_error{ "Failure to get device properties" }; - } - pmlog_verb(v::tele_gpu)("ctlGetDeviceProperties output") - .pmwatch(GetName()).pmwatch(GetDeviceId()) - .pmwatch(ref::DumpGenerated(properties)) - .pmwatch(deviceLuid.HighPart).pmwatch(deviceLuid.LowPart); - - if (properties.device_type != CTL_DEVICE_TYPE_GRAPHICS) { - throw NonGraphicsDeviceException{}; - } - - // check for alchemist (used to enable features whose support not reported by IGCL) - // use device name that match Arc followed by A### part number pattern - isAlchemist = std::regex_search(GetName(), std::regex{ R"(Arc.*A\d{3})" }); - pmlog_verb(v::tele_gpu)("Alchemist detection") - .pmwatch(GetName()).pmwatch(GetDeviceId()).pmwatch(isAlchemist); - - // errors are reported inside this function - // do not hard-fail on memory module issues, so no need to check error return code - EnumerateMemoryModules(); - - // get count of power domains - uint32_t powerDomainCount = 0; - if (auto result = ctlEnumPowerDomains(deviceHandle, &powerDomainCount, nullptr); - result == CTL_RESULT_SUCCESS) { - powerDomains.resize(powerDomainCount); - // get power domain handles - if (auto result = ctlEnumPowerDomains(deviceHandle, &powerDomainCount, powerDomains.data()); - result == CTL_RESULT_SUCCESS) { - pmlog_verb(v::tele_gpu)("ctlEnumPowerDomains(output)") - .pmwatch(GetName()).pmwatch(GetDeviceId()).pmwatch(ref::DumpGenerated(powerDomains)); - } - else { - pmlog_warn("ctlEnumPowerDomains(enumeration) failed") - .code(result).pmwatch(GetName()).pmwatch(GetDeviceId()); - } - } - else { - pmlog_warn("ctlEnumPowerDomains(count) failed") - .code(result).pmwatch(GetName()).pmwatch(GetDeviceId()); - } - - // enumerate fans - uint32_t fanCount = 0; - if (auto res = ctlEnumFans(deviceHandle, &fanCount, nullptr); res == CTL_RESULT_SUCCESS) { - if (fanCount > 0) { - std::vector fanHandles(fanCount); - if (auto res = ctlEnumFans(deviceHandle, &fanCount, fanHandles.data()); res == CTL_RESULT_SUCCESS) { - for (auto&&[iFan, hFan] : vi::enumerate(fanHandles)) { - if (hFan) { - ctl_fan_properties_t props{ .Size = sizeof(ctl_fan_properties_t) }; - if (auto res = ctlFanGetProperties(hFan, &props); res != CTL_RESULT_SUCCESS) { - pmlog_warn(std::format( - "ctlFanGetProperties failed for fan #{}", - iFan)).code(res).pmwatch(GetName()).pmwatch(GetDeviceId()); - maxFanSpeedsRpm_.push_back(0); - } - pmlog_verb(v::tele_gpu)( - "ctlFanGetProperties output") - .pmwatch(GetName()).pmwatch(GetDeviceId()).pmwatch(iFan) - .pmwatch(ref::DumpGenerated(props)); - maxFanSpeedsRpm_.push_back(props.maxRPM); - } - else { - pmlog_warn("null handle from ctlEnumFans") - .pmwatch(GetName()).pmwatch(GetDeviceId()); - maxFanSpeedsRpm_.push_back(0); - } - } - } - else { - pmlog_warn("ctlEnumFans(handles) failed") - .code(res).pmwatch(GetName()).pmwatch(GetDeviceId()); - } - } - } - else { - pmlog_warn("ctlEnumFans(count) failed").code(res) - .pmwatch(GetName()).pmwatch(GetDeviceId()); - } - } - - PresentMonPowerTelemetryInfo IntelPowerTelemetryAdapter::Sample() noexcept - { - pmlog_verb(v::tele_gpu)("telemetry poll tick").pmwatch(GetName()).pmwatch(GetDeviceId()); - - LARGE_INTEGER qpc; - QueryPerformanceCounter(&qpc); - bool success = true; - PresentMonPowerTelemetryInfo sample{ - .qpc = (uint64_t)qpc.QuadPart, - }; - - ctl_power_telemetry_t currentSample{ - .Size = sizeof(ctl_power_telemetry_t), - .Version = 1, - }; - if (const auto result = ctlPowerTelemetryGet(deviceHandle, ¤tSample); - result != CTL_RESULT_SUCCESS) { - success = false; - pmlog_warn("ctlPowerTelemetryGet failed").code(result).every(std::chrono::seconds{ 60 }) - .pmwatch(GetName()).pmwatch(GetDeviceId()); - } - pmlog_verb(v::tele_gpu)("ctlPowerTelemetryGet output") - .pmwatch(GetName()).pmwatch(GetDeviceId()).pmwatch(ref::DumpGenerated(currentSample)); - - // Query memory state and bandwidth if supported - ctl_mem_state_t memory_state = {.Size = sizeof(ctl_mem_state_t)}; - ctl_mem_bandwidth_t memory_bandwidth = { - .Size = sizeof(ctl_mem_bandwidth_t), - .Version = 1, - }; - bool hasMemoryState = false; - bool hasMemoryBandwidth = false; - // Question: why are we only using the first element of memoryModules here? - if (memoryModules.size() > 0) { - if (const auto result = ctlMemoryGetState(memoryModules[0], &memory_state); - result != CTL_RESULT_SUCCESS) { - success = false; - pmlog_warn("ctlMemoryGetState failed").code(result).every(std::chrono::seconds{ 60 }) - .pmwatch(GetName()).pmwatch(GetDeviceId()); - } - else { - hasMemoryState = true; - } - pmlog_verb(v::tele_gpu)("ctlMemoryGetState output") - .pmwatch(GetName()).pmwatch(GetDeviceId()).pmwatch(ref::DumpGenerated(memory_state)); - - if (const auto result = ctlMemoryGetBandwidth(memoryModules[0], &memory_bandwidth); - result != CTL_RESULT_SUCCESS) { - success = false; - pmlog_warn("ctlMemoryGetBandwidth failed").code(result).every(std::chrono::seconds{ 60 }) - .pmwatch(GetName()).pmwatch(GetDeviceId()); - } - else { - hasMemoryBandwidth = true; - } - pmlog_verb(v::tele_gpu)("ctlMemoryGetBandwidth output") - .pmwatch(GetName()).pmwatch(GetDeviceId()).pmwatch(ref::DumpGenerated(memory_bandwidth)); - } - - std::optional gpu_sustained_power_limit_mw; - if (!powerDomains.empty()) { - ctl_power_limits_t limits{ - .Size = sizeof(ctl_power_limits_t), - }; - if (const auto result = ctlPowerGetLimits(powerDomains[0], &limits); - result == CTL_RESULT_SUCCESS) { - if (limits.sustainedPowerLimit.enabled) { - gpu_sustained_power_limit_mw = (double)limits.sustainedPowerLimit.power; - } - pmlog_verb(v::tele_gpu)("ctlPowerGetLimits output").pmwatch(GetName()) - .pmwatch(GetDeviceId()).pmwatch(ref::DumpGenerated(limits)); - } - else { - success = false; - pmlog_warn("ctlPowerGetLimits failed").code(result).every(std::chrono::seconds{ 60 }) - .pmwatch(GetName()).pmwatch(GetDeviceId()); - } - } - - success = GatherSampleData(currentSample, memory_state, hasMemoryState, - memory_bandwidth, hasMemoryBandwidth, gpu_sustained_power_limit_mw, (uint64_t)qpc.QuadPart, sample) && success; - - (void)success; - return sample; - } - - PM_DEVICE_VENDOR IntelPowerTelemetryAdapter::GetVendor() const noexcept - { - return PM_DEVICE_VENDOR::PM_DEVICE_VENDOR_INTEL; - } - - std::string IntelPowerTelemetryAdapter::GetName() const noexcept - { - return properties.name; - } - - uint64_t IntelPowerTelemetryAdapter::GetDedicatedVideoMemory() const noexcept - { - ctl_mem_state_t memory_state = {.Size = sizeof(ctl_mem_state_t)}; - uint64_t video_mem_size = 0; - if (memoryModules.size() > 0) { - if (const auto result = ctlMemoryGetState(memoryModules[0], &memory_state); - result == CTL_RESULT_SUCCESS) { - video_mem_size = memory_state.size; - } - else { - pmlog_warn("ctlMemoryGetState failed").code(result) - .pmwatch(GetName()).pmwatch(GetDeviceId()); - } - pmlog_verb(v::tele_gpu)("ctlMemoryGetState output") - .pmwatch(GetName()).pmwatch(GetDeviceId()).pmwatch(ref::DumpGenerated(memory_state)); - } - return video_mem_size; - } - - uint64_t IntelPowerTelemetryAdapter::GetVideoMemoryMaxBandwidth() const noexcept - { - ctl_mem_bandwidth_t memoryBandwidth = { - .Size = sizeof(ctl_mem_bandwidth_t), - .Version = 1, - }; - uint64_t videoMemMaxBandwidth = 0; - if (memoryModules.size() > 0) { - if (const auto result = ctlMemoryGetBandwidth(memoryModules[0], &memoryBandwidth); - result == CTL_RESULT_SUCCESS) { - videoMemMaxBandwidth = memoryBandwidth.maxBandwidth; - } - else { - pmlog_warn("ctlMemoryGetBandwidth failed") - .code(result).pmwatch(GetName()).pmwatch(GetDeviceId()); - } - pmlog_verb(v::tele_gpu)("ctlMemoryGetBandwidth output") - .pmwatch(GetName()).pmwatch(GetDeviceId()).pmwatch(ref::DumpGenerated(memoryBandwidth)); - } - return videoMemMaxBandwidth; - } - - double IntelPowerTelemetryAdapter::GetSustainedPowerLimit() const noexcept - { - double gpuSustainedPowerLimit = 0.; - if (!powerDomains.empty()) { - ctl_power_limits_t limits{ - .Size = sizeof(ctl_power_limits_t), - }; - if (const auto result = ctlPowerGetLimits(powerDomains[0], &limits); - result == CTL_RESULT_SUCCESS) { - gpuSustainedPowerLimit = (double)limits.sustainedPowerLimit.power; - pmlog_verb(v::tele_gpu)("ctlPowerGetLimits output") - .pmwatch(GetName()).pmwatch(GetDeviceId()) - .pmwatch(ref::DumpGenerated(limits)); - } - else { - pmlog_warn("ctlPowerGetLimits failed").code(result) - .pmwatch(GetName()).pmwatch(GetDeviceId()); - } - } - // Control lib returns back in milliwatts - return gpuSustainedPowerLimit / 1000.; - } - - uint64_t IntelPowerTelemetryAdapter::GetAdapterId() const noexcept - { - // LUID is a struct with LowPart (DWORD) and HighPart (LONG) - // We pack it into a uint64_t - uint64_t id = 0; - id |= (uint64_t)deviceLuid.LowPart; - id |= (uint64_t)deviceLuid.HighPart << 32; - return id; - } - // private implementation functions - - ctl_result_t IntelPowerTelemetryAdapter::EnumerateMemoryModules() - { - // first call ctlEnumMemoryModules with nullptr to get number of modules - // and resize vector to accomodate - uint32_t memory_module_count = 0; - if (auto result = ctlEnumMemoryModules(deviceHandle, &memory_module_count, - nullptr); result != CTL_RESULT_SUCCESS) - { - pmlog_warn("ctlEnumMemoryModules(count) failed") - .code(result).pmwatch(GetName()).pmwatch(GetDeviceId()); - return result; - } - memoryModules.resize(size_t(memory_module_count)); - // call ctlEnumMemoryModules to get the actual module data now - if (auto result = ctlEnumMemoryModules(deviceHandle, &memory_module_count, - memoryModules.data()); result != CTL_RESULT_SUCCESS) - { - pmlog_warn("ctlEnumMemoryModules(data) failed") - .code(result).pmwatch(GetName()).pmwatch(GetDeviceId()); - memoryModules.clear(); - return result; - } - pmlog_verb(v::tele_gpu)("ctlEnumMemoryModules output") - .pmwatch(GetName()).pmwatch(GetDeviceId()).pmwatch(ref::DumpGenerated(memoryModules)); - - return CTL_RESULT_SUCCESS; - } - - bool IntelPowerTelemetryAdapter::GatherSampleData(ctl_power_telemetry_t& currentSample, - ctl_mem_state_t& memory_state, - bool has_memory_state, - ctl_mem_bandwidth_t& memory_bandwidth, - bool has_memory_bandwidth, - std::optional gpu_sustained_power_limit_mw, - uint64_t qpc, - PresentMonPowerTelemetryInfo& sample) - { - bool success = true; - - if (const auto result = GetTimeDelta(currentSample); - result != CTL_RESULT_SUCCESS) - { - success = false; - pmlog_warn("ctlPowerTelemetryGet timestamp delta processing failed").code(result).every(std::chrono::seconds{ 60 }) - .pmwatch(GetName()).pmwatch(GetDeviceId()); - } - - sample.qpc = qpc; - - if (previousSample) { - - if (const auto result = GetGPUPowerTelemetryData( - currentSample, sample); result != CTL_RESULT_SUCCESS) - { - success = false; - pmlog_warn("ctlPowerTelemetryGet GPU field processing failed") - .code(result).every(std::chrono::seconds{ 60 }).pmwatch(GetName()).pmwatch(GetDeviceId()); - } - - if (const auto result = GetVramPowerTelemetryData( - currentSample, sample); result != CTL_RESULT_SUCCESS) - { - success = false; - pmlog_warn("ctlPowerTelemetryGet VRAM field processing failed") - .code(result).every(std::chrono::seconds{ 60 }).pmwatch(GetName()).pmwatch(GetDeviceId()); - } - - if (const auto result = GetFanPowerTelemetryData(currentSample, - sample); result != CTL_RESULT_SUCCESS) - { - success = false; - pmlog_warn("ctlPowerTelemetryGet fan field processing failed") - .code(result).every(std::chrono::seconds{ 60 }).pmwatch(GetName()).pmwatch(GetDeviceId()); - } - - if (const auto result = GetPsuPowerTelemetryData( - currentSample, sample); result != CTL_RESULT_SUCCESS) - { - success = false; - pmlog_warn("ctlPowerTelemetryGet PSU field processing failed") - .code(result).every(std::chrono::seconds{ 60 }).pmwatch(GetName()).pmwatch(GetDeviceId()); - } - - // Get memory state and bandwidth data - if (memoryModules.size() > 0) { - if (has_memory_state) { - GetMemStateTelemetryData(memory_state, - sample); - } - if (has_memory_bandwidth) { - GetMemBandwidthData(memory_bandwidth, - sample); - } - } - - // Save and convert the gpu sustained power limit - sample.gpu_sustained_power_limit_w = - gpu_sustained_power_limit_mw.value_or(0.) / 1000.; - if (gpu_sustained_power_limit_mw) { - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_sustained_power_limit); - } - - pmlog_verb(v::tele_gpu)("telemetry sample assembled") - .pmwatch(GetName()).pmwatch(GetDeviceId()).pmwatch(ref::DumpStatic(sample)); - } - - // Save off the raw control library data for calculating time delta - // and usage data. - if (const auto result = SaveTelemetry(currentSample); - result != CTL_RESULT_SUCCESS) - { - success = false; - pmlog_warn("ctlPowerTelemetryGet sample cache update failed").code(result).every(std::chrono::seconds{ 60 }) - .pmwatch(GetName()).pmwatch(GetDeviceId()); - } - - return success; - } - - // TODO: stop using CTL stuff for non-ctl logic - // TODO: better functional programming - ctl_result_t IntelPowerTelemetryAdapter::GetTimeDelta(const ctl_power_telemetry_t& currentSample) - { - if (!previousSample) { - // We do not have a previous power telemetry item to calculate time - // delta against. - time_delta_ = 0.f; - } - else { - if (currentSample.timeStamp.type == CTL_DATA_TYPE_DOUBLE) { - time_delta_ = currentSample.timeStamp.value.datadouble - - previousSample->timeStamp.value.datadouble; - } - else { - return CTL_RESULT_ERROR_INVALID_ARGUMENT; - } - } - - return CTL_RESULT_SUCCESS; - } - - ctl_result_t IntelPowerTelemetryAdapter::GetGPUPowerTelemetryData( - const ctl_power_telemetry_t& currentSample, - PresentMonPowerTelemetryInfo& pm_gpu_power_telemetry_info) - { - ctl_result_t result; - - if (!previousSample) { - return CTL_RESULT_ERROR_INVALID_ARGUMENT; - } - - result = GetInstantaneousPowerTelemetryItem( - currentSample.timeStamp, - pm_gpu_power_telemetry_info.time_stamp, - GpuTelemetryCapBits::time_stamp); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - result = GetInstantaneousPowerTelemetryItem( - currentSample.gpuVoltage, - pm_gpu_power_telemetry_info.gpu_voltage_v, - GpuTelemetryCapBits::gpu_voltage); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - result = GetInstantaneousPowerTelemetryItem( - currentSample.gpuCurrentClockFrequency, - pm_gpu_power_telemetry_info.gpu_frequency_mhz, - GpuTelemetryCapBits::gpu_frequency); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - result = GetInstantaneousPowerTelemetryItem( - currentSample.gpuCurrentTemperature, - pm_gpu_power_telemetry_info.gpu_temperature_c, - GpuTelemetryCapBits::gpu_temperature); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - result = GetPowerTelemetryItemUsage( - currentSample.gpuEnergyCounter, - previousSample->gpuEnergyCounter, - pm_gpu_power_telemetry_info.gpu_power_w, - GpuTelemetryCapBits::gpu_power); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - result = GetPowerTelemetryItemUsage( - currentSample.totalCardEnergyCounter, - previousSample->totalCardEnergyCounter, - pm_gpu_power_telemetry_info.gpu_card_power_w, - GpuTelemetryCapBits::gpu_card_power); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - result = GetPowerTelemetryItemUsagePercent( - currentSample.globalActivityCounter, - previousSample->globalActivityCounter, - pm_gpu_power_telemetry_info.gpu_utilization, - GpuTelemetryCapBits::gpu_utilization); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - result = GetPowerTelemetryItemUsagePercent( - currentSample.renderComputeActivityCounter, - previousSample->renderComputeActivityCounter, - pm_gpu_power_telemetry_info.gpu_render_compute_utilization, - GpuTelemetryCapBits::gpu_render_compute_utilization); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - result = GetPowerTelemetryItemUsagePercent( - currentSample.mediaActivityCounter, - previousSample->mediaActivityCounter, - pm_gpu_power_telemetry_info.gpu_media_utilization, - GpuTelemetryCapBits::gpu_media_utilization); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - pm_gpu_power_telemetry_info.gpu_power_limited = - currentSample.gpuPowerLimited; - pm_gpu_power_telemetry_info.gpu_temperature_limited = - currentSample.gpuTemperatureLimited; - pm_gpu_power_telemetry_info.gpu_current_limited = - currentSample.gpuCurrentLimited; - pm_gpu_power_telemetry_info.gpu_voltage_limited = - currentSample.gpuVoltageLimited; - pm_gpu_power_telemetry_info.gpu_utilization_limited = - currentSample.gpuUtilizationLimited; - - // On Intel all GPU limitation indicators are active except... - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_power_limited); - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_temperature_limited); - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_voltage_limited); - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_utilization_limited); - - // gpu_current_limited perf limit reason seems not supported on BMG - // because there is no bSupported flags for the perf limit reasons - // we detect alchemist and use this as a proxy for support - if (isAlchemist) { - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_current_limited); - } - - result = GetInstantaneousPowerTelemetryItem( - currentSample.gpuEffectiveClock, - pm_gpu_power_telemetry_info.gpu_effective_frequency_mhz, - GpuTelemetryCapBits::gpu_effective_frequency); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - result = GetInstantaneousPowerTelemetryItem( - currentSample.gpuVrTemp, - pm_gpu_power_telemetry_info.gpu_voltage_regulator_temperature_c, - GpuTelemetryCapBits::gpu_voltage_regulator_temperature); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - result = GetInstantaneousPowerTelemetryItem( - currentSample.vramCurrentEffectiveFrequency, - pm_gpu_power_telemetry_info.gpu_mem_effective_bandwidth_gbps, - GpuTelemetryCapBits::gpu_mem_effective_bandwidth); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - result = GetInstantaneousPowerTelemetryItem( - currentSample.gpuOverVoltagePercent, - pm_gpu_power_telemetry_info.gpu_overvoltage_percent, - GpuTelemetryCapBits::gpu_overvoltage_percent); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - result = GetInstantaneousPowerTelemetryItem( - currentSample.gpuTemperaturePercent, - pm_gpu_power_telemetry_info.gpu_temperature_percent, - GpuTelemetryCapBits::gpu_temperature_percent); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - result = GetInstantaneousPowerTelemetryItem( - currentSample.gpuPowerPercent, - pm_gpu_power_telemetry_info.gpu_power_percent, - GpuTelemetryCapBits::gpu_power_percent); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - return result; - } - - ctl_result_t IntelPowerTelemetryAdapter::GetVramPowerTelemetryData( - const ctl_power_telemetry_t& currentSample, - PresentMonPowerTelemetryInfo& pm_gpu_power_telemetry_info) - { - ctl_result_t result; - - if (!previousSample) { - return CTL_RESULT_ERROR_INVALID_ARGUMENT; - } - - result = GetInstantaneousPowerTelemetryItem(currentSample.vramVoltage, - pm_gpu_power_telemetry_info.vram_voltage_v, - GpuTelemetryCapBits::vram_voltage); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - result = GetInstantaneousPowerTelemetryItem( - currentSample.vramCurrentClockFrequency, - pm_gpu_power_telemetry_info.vram_frequency_mhz, - GpuTelemetryCapBits::vram_frequency); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - result = GetInstantaneousPowerTelemetryItem( - currentSample.vramCurrentEffectiveFrequency, - pm_gpu_power_telemetry_info.vram_effective_frequency_gbps, - GpuTelemetryCapBits::vram_effective_frequency); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - result = GetInstantaneousPowerTelemetryItem( - currentSample.vramCurrentTemperature, - pm_gpu_power_telemetry_info.vram_temperature_c, - GpuTelemetryCapBits::vram_temperature); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - // bandwidth telemetry has 2 possible paths for acquisition - using namespace pmon::util; - if (useNewBandwidthTelemetry) { - pmlog_verb(v::tele_gpu)("ctlPowerTelemetryGet VRAM bandwidth V1 path") - .pmwatch(GetName()).pmwatch(GetDeviceId()); - double gpuMemReadBandwidthMegabytesPerSecond = 0; - result = GetInstantaneousPowerTelemetryItem( - currentSample.vramReadBandwidth, - gpuMemReadBandwidthMegabytesPerSecond, - GpuTelemetryCapBits::gpu_mem_read_bandwidth); - // we need bandwidth in bits per second, IGCL V1 gives in megabytes per second - pm_gpu_power_telemetry_info.gpu_mem_read_bandwidth_bps = ConvertMagnitudePrefix( - gpuMemReadBandwidthMegabytesPerSecond * 8., - MagnitudePrefix::Mega, - MagnitudePrefix::Base); - if (result != CTL_RESULT_SUCCESS || - !(HasTelemetryCapBit(GpuTelemetryCapBits::gpu_mem_read_bandwidth))) { - useNewBandwidthTelemetry = false; - pmlog_info("ctlPowerTelemetryGet.vramReadBandwidth unavailable, falling back to V0 counters") - .code(result).pmwatch(GetName()).pmwatch(GetDeviceId()) - .pmwatch(HasTelemetryCapBit(GpuTelemetryCapBits::gpu_mem_read_bandwidth)); - } - } - if (useNewBandwidthTelemetry) { - double gpuMemWriteBandwidthMegabytesPerSecond = 0; - result = GetInstantaneousPowerTelemetryItem( - currentSample.vramWriteBandwidth, - gpuMemWriteBandwidthMegabytesPerSecond, - GpuTelemetryCapBits::gpu_mem_write_bandwidth); - // we need bandwidth in bits per second, IGCL V1 gives in megabytes per second - pm_gpu_power_telemetry_info.gpu_mem_write_bandwidth_bps = ConvertMagnitudePrefix( - gpuMemWriteBandwidthMegabytesPerSecond * 8., - MagnitudePrefix::Mega, - MagnitudePrefix::Base); - if (result != CTL_RESULT_SUCCESS || - !(HasTelemetryCapBit(GpuTelemetryCapBits::gpu_mem_write_bandwidth))) { - useNewBandwidthTelemetry = false; - pmlog_info("ctlPowerTelemetryGet.vramWriteBandwidth unavailable, falling back to V0 counters") - .code(result).pmwatch(GetName()).pmwatch(GetDeviceId()) - .pmwatch(HasTelemetryCapBit(GpuTelemetryCapBits::gpu_mem_write_bandwidth)); - } - } - if (!useNewBandwidthTelemetry) { - pmlog_verb(v::tele_gpu)("ctlPowerTelemetryGet VRAM bandwidth counter path") - .pmwatch(GetName()).pmwatch(GetDeviceId()); - result = GetPowerTelemetryItemUsage( - currentSample.vramReadBandwidthCounter, - previousSample->vramReadBandwidthCounter, - pm_gpu_power_telemetry_info.gpu_mem_read_bandwidth_bps, - GpuTelemetryCapBits::gpu_mem_read_bandwidth); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - result = GetPowerTelemetryItemUsage( - currentSample.vramWriteBandwidthCounter, - previousSample->vramWriteBandwidthCounter, - pm_gpu_power_telemetry_info.gpu_mem_write_bandwidth_bps, - GpuTelemetryCapBits::gpu_mem_write_bandwidth); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - } - - result = GetPowerTelemetryItemUsage(currentSample.vramEnergyCounter, - previousSample->vramEnergyCounter, - pm_gpu_power_telemetry_info.vram_power_w, - GpuTelemetryCapBits::vram_power); - if (result != CTL_RESULT_SUCCESS) { - return result; - } - - // On Intel all VRAM limitation indicators are deprecated / return false - // GpuTelemetryCapBits::vram_power_limited - // GpuTelemetryCapBits::vram_temperature_limited - // GpuTelemetryCapBits::vram_current_limited - // GpuTelemetryCapBits::vram_voltage_limited - // GpuTelemetryCapBits::vram_utilization_limited - - return result; - } - - ctl_result_t IntelPowerTelemetryAdapter::GetFanPowerTelemetryData( - const ctl_power_telemetry_t& currentSample, - PresentMonPowerTelemetryInfo& pm_gpu_power_telemetry_info) - { - ctl_result_t result = CTL_RESULT_SUCCESS; - - for (uint32_t i = 0; i < CTL_FAN_COUNT; i++) { - try { - const auto fanSpeedCapBit = GetFanSpeedTelemetryCapBit_(i); - result = GetInstantaneousPowerTelemetryItem( - currentSample.fanSpeed[i], - pm_gpu_power_telemetry_info.fan_speed_rpm[i], - fanSpeedCapBit); - if (result != CTL_RESULT_SUCCESS) { - break; - } - if (HasTelemetryCapBit(fanSpeedCapBit) && maxFanSpeedsRpm_[i] > 0) { - SetTelemetryCapBit(GetMaxFanSpeedTelemetryCapBit_(i)); - pm_gpu_power_telemetry_info.max_fan_speed_rpm[i] = maxFanSpeedsRpm_[i]; - } - } catch (...) { - result = CTL_RESULT_ERROR_INVALID_ARGUMENT; - } - } - - return result; - } - - ctl_result_t IntelPowerTelemetryAdapter::GetPsuPowerTelemetryData( - const ctl_power_telemetry_t& currentSample, - PresentMonPowerTelemetryInfo& pm_gpu_power_telemetry_info) - { - ctl_result_t result = CTL_RESULT_SUCCESS; - - if (!previousSample) { - return CTL_RESULT_ERROR_INVALID_ARGUMENT; - } - - for (uint32_t i = 0; i < CTL_PSU_COUNT; i++) { - if (currentSample.psu[i].bSupported) { - GpuTelemetryCapBits psu_telemetry_bit; - try { - psu_telemetry_bit = GetPsuTelemetryCapBit_(i); - pm_gpu_power_telemetry_info.psu[i].psu_type = - PresentMonPsuType(currentSample.psu[i].psuType); - result = GetInstantaneousPowerTelemetryItem( - currentSample.psu[i].voltage, - pm_gpu_power_telemetry_info.psu[i].psu_voltage, - psu_telemetry_bit); - if (result != CTL_RESULT_SUCCESS) { - break; - } - result = GetPowerTelemetryItemUsage( - currentSample.psu[i].energyCounter, - previousSample->psu[i].energyCounter, - pm_gpu_power_telemetry_info.psu[i].psu_power, - psu_telemetry_bit); - if (result != CTL_RESULT_SUCCESS) { - break; - } - } catch (...) { - result = CTL_RESULT_ERROR_INVALID_ARGUMENT; - break; - } - } - else { - pm_gpu_power_telemetry_info.psu[i].psu_type = - PresentMonPsuType::None; - pm_gpu_power_telemetry_info.psu[i].psu_power = 0.0f; - pm_gpu_power_telemetry_info.psu[i].psu_voltage = 0.0f; - } - } - - return result; - } - - void IntelPowerTelemetryAdapter::GetMemStateTelemetryData( - const ctl_mem_state_t& mem_state, - PresentMonPowerTelemetryInfo& pm_gpu_power_telemetry_info) { - pm_gpu_power_telemetry_info.gpu_mem_total_size_b = mem_state.size; - pm_gpu_power_telemetry_info.gpu_mem_used_b = mem_state.size - mem_state.free; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_mem_size); - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_mem_used); - return; - } - - void IntelPowerTelemetryAdapter::GetMemBandwidthData( - const ctl_mem_bandwidth_t& mem_bandwidth, - PresentMonPowerTelemetryInfo& pm_gpu_power_telemetry_info) { - pm_gpu_power_telemetry_info.gpu_mem_max_bandwidth_bps = mem_bandwidth.maxBandwidth; - gpu_mem_max_bw_cache_value_bps_ = mem_bandwidth.maxBandwidth; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_mem_max_bandwidth); - return; - } - - ctl_result_t IntelPowerTelemetryAdapter::GetInstantaneousPowerTelemetryItem( - const ctl_oc_telemetry_item_t& telemetry_item, - double& pm_telemetry_value, GpuTelemetryCapBits telemetry_cap_bit) - { - if (telemetry_item.bSupported) { - if (telemetry_item.type == CTL_DATA_TYPE_DOUBLE) { - pm_telemetry_value = telemetry_item.value.datadouble; - SetTelemetryCapBit(telemetry_cap_bit); - } - else { - // Expecting a double return type here - return CTL_RESULT_ERROR_INVALID_ARGUMENT; - } - } - else { - pm_telemetry_value = 0.0; - } - return CTL_RESULT_SUCCESS; - } - - ctl_result_t IntelPowerTelemetryAdapter::GetPowerTelemetryItemUsagePercent( - const ctl_oc_telemetry_item_t& current_telemetry_item, - const ctl_oc_telemetry_item_t& previous_telemetry_item, - double& pm_telemetry_value, GpuTelemetryCapBits telemetry_cap_bit) - { - if (current_telemetry_item.bSupported) { - if (current_telemetry_item.type == CTL_DATA_TYPE_DOUBLE) { - auto data_delta = current_telemetry_item.value.datadouble - - previous_telemetry_item.value.datadouble; - pm_telemetry_value = (data_delta / time_delta_) * 100.0f; - SetTelemetryCapBit(telemetry_cap_bit); - } - else { - // Expecting a double return type here - return CTL_RESULT_ERROR_INVALID_ARGUMENT; - } - } - return CTL_RESULT_SUCCESS; - } - - - ctl_result_t IntelPowerTelemetryAdapter::GetPowerTelemetryItemUsage( - const ctl_oc_telemetry_item_t& current_telemetry_item, - const ctl_oc_telemetry_item_t& previous_telemetry_item, - double& pm_telemetry_value, GpuTelemetryCapBits telemetry_cap_bit) - { - if (current_telemetry_item.bSupported) { - if (current_telemetry_item.type == CTL_DATA_TYPE_DOUBLE) { - auto data_delta = current_telemetry_item.value.datadouble - - previous_telemetry_item.value.datadouble; - pm_telemetry_value = (data_delta / time_delta_); - SetTelemetryCapBit(telemetry_cap_bit); - if (telemetry_cap_bit == GpuTelemetryCapBits::vram_power) { - if (current_telemetry_item.value.datadouble < previous_telemetry_item.value.datadouble) { - pm_telemetry_value = gpu_mem_power_cache_value_w_; - } - else { - gpu_mem_power_cache_value_w_ = pm_telemetry_value; - } - } - } - else if (current_telemetry_item.type == CTL_DATA_TYPE_INT64) { - auto data_delta = current_telemetry_item.value.data64 - - previous_telemetry_item.value.data64; - pm_telemetry_value = static_cast(data_delta) / time_delta_; - SetTelemetryCapBit(telemetry_cap_bit); - } - else if (current_telemetry_item.type == CTL_DATA_TYPE_UINT64) { - auto data_delta = current_telemetry_item.value.datau64 - - previous_telemetry_item.value.datau64; - pm_telemetry_value = - static_cast(data_delta) / time_delta_; - SetTelemetryCapBit(telemetry_cap_bit); - // stopgap measure for bad vram bandwidth telemetry coming out of V0 api - if (telemetry_cap_bit == GpuTelemetryCapBits::gpu_mem_read_bandwidth && !useNewBandwidthTelemetry) { - if ((current_telemetry_item.value.datau64 < previous_telemetry_item.value.datau64) || - ((current_telemetry_item.value.datau64 - previous_telemetry_item.value.datau64) > gpu_mem_max_bw_cache_value_bps_)) { - pm_telemetry_value = gpu_mem_read_bw_cache_value_bps_; - } - else { - gpu_mem_read_bw_cache_value_bps_ = pm_telemetry_value; - } - } - } - else { - // Expecting a double return type here - return CTL_RESULT_ERROR_INVALID_ARGUMENT; - } - } - return CTL_RESULT_SUCCESS; - } - - ctl_result_t IntelPowerTelemetryAdapter::SaveTelemetry( - const ctl_power_telemetry_t& currentSample) - { - if (currentSample.timeStamp.type == CTL_DATA_TYPE_DOUBLE) { - previousSample = currentSample; - } - else { - return CTL_RESULT_ERROR_INVALID_ARGUMENT; - } - - return CTL_RESULT_SUCCESS; - } -} diff --git a/IntelPresentMon/ControlLib/IntelPowerTelemetryProvider.h b/IntelPresentMon/ControlLib/IntelPowerTelemetryProvider.h deleted file mode 100644 index b51d3f33..00000000 --- a/IntelPresentMon/ControlLib/IntelPowerTelemetryProvider.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#pragma once -#define NOMINMAX -#include -#include -#include -#include -#include -#include "igcl_api.h" -#include "PresentMonPowerTelemetry.h" -#include "PowerTelemetryProvider.h" -#include "DeviceIdAllocator.h" - -namespace pwr::intel -{ - class IntelPowerTelemetryProvider : public PowerTelemetryProvider - { - public: - explicit IntelPowerTelemetryProvider(DeviceIdAllocator& allocator); - IntelPowerTelemetryProvider(const IntelPowerTelemetryProvider& t) = delete; - IntelPowerTelemetryProvider& operator=(const IntelPowerTelemetryProvider& t) = delete; - ~IntelPowerTelemetryProvider() override; - const std::vector>& GetAdapters() noexcept override; - uint32_t GetAdapterCount() const noexcept override; - - private: - ctl_api_handle_t apiHandle = nullptr; - std::vector> adapterPtrs; - }; -} diff --git a/IntelPresentMon/ControlLib/IntelPowerTelemetryProvider_old.cpp b/IntelPresentMon/ControlLib/IntelPowerTelemetryProvider_old.cpp deleted file mode 100644 index e647bcfb..00000000 --- a/IntelPresentMon/ControlLib/IntelPowerTelemetryProvider_old.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#include "IntelPowerTelemetryProvider.h" -#include "IntelPowerTelemetryAdapter.h" -#include "Logging.h" -#include "Exceptions.h" -#include "../CommonUtilities/ref/GeneratedReflection.h" - -using namespace pmon; -using namespace util; -using v = log::V; - -namespace pwr::intel -{ - IntelPowerTelemetryProvider::IntelPowerTelemetryProvider(DeviceIdAllocator& allocator) - { - // TODO(megalvan): Currently using the default Id of all zeros. Do we need - // to obtain a legit application Id or is default fine? - ctl_init_args_t ctl_init_args{ - .Size = sizeof(ctl_init_args), - .AppVersion = CTL_MAKE_VERSION(CTL_IMPL_MAJOR_VERSION, CTL_IMPL_MINOR_VERSION), - .flags = CTL_INIT_FLAG_USE_LEVEL_ZERO, - }; - - // initialize the igcl api - if (const auto result = ctlInit(&ctl_init_args, &apiHandle); result != CTL_RESULT_SUCCESS) { - if (result != CTL_RESULT_ERROR_NOT_INITIALIZED) { - pmlog_error("ctlInit failed").code(result); - } - throw Except("Unable to initialize Intel Graphics Control Library"); - } - pmlog_verb(v::tele_gpu)("ctlInit input args") - .pmwatch(ref::DumpGenerated(ctl_init_args)); - - pmlog_info(std::format("ctlInit supported version={}.{}", - CTL_MAJOR_VERSION(ctl_init_args.SupportedVersion), - CTL_MINOR_VERSION(ctl_init_args.SupportedVersion) - )); - - // enumerate devices available via igcl (get a list of device handles) - std::vector handles; - { - uint32_t count = 0; - if (const auto result = ctlEnumerateDevices(apiHandle, &count, nullptr); result != CTL_RESULT_SUCCESS) { - pmlog_error("ctlEnumerateDevices(count) failed") - .code(result); - throw std::runtime_error{ "failed igcl device enumeration (get count)" }; - } - pmlog_verb(v::tele_gpu)("ctlEnumerateDevices(count) output") - .pmwatch(count); - - handles.resize(count); - if (const auto result = ctlEnumerateDevices(apiHandle, &count, handles.data()); result != CTL_RESULT_SUCCESS) { - pmlog_error("ctlEnumerateDevices(list) failed") - .code(result); - throw std::runtime_error{ "failed igcl device enumeration (get list)" }; - } - } - - // create adaptor object for each device handle - for (auto& handle : handles) - { - const auto deviceId = allocator.Next(); - try { - adapterPtrs.push_back(std::make_shared(deviceId, handle)); - } - catch (const IntelPowerTelemetryAdapter::NonGraphicsDeviceException&) {} - catch (const std::exception& e) { - TELE_ERR(std::format( - "IntelPowerTelemetryAdapter construction failed: {}", - e.what())).pmwatch(deviceId); - } - catch (...) { - TELE_ERR("IntelPowerTelemetryAdapter construction failed: unknown error").pmwatch(deviceId); - } - } - } - - IntelPowerTelemetryProvider::~IntelPowerTelemetryProvider() - { - // want to make sure we clear adapters *before* we close the API - adapterPtrs.clear(); - - if (apiHandle) - { - ctlClose(apiHandle); - } - } - - const std::vector>& IntelPowerTelemetryProvider::GetAdapters() noexcept - { - return adapterPtrs; - } - - uint32_t IntelPowerTelemetryProvider::GetAdapterCount() const noexcept - { - return (uint32_t)adapterPtrs.size(); - } -} diff --git a/IntelPresentMon/ControlLib/Logging.h b/IntelPresentMon/ControlLib/Logging.h index 996c481b..e2d775c7 100644 --- a/IntelPresentMon/ControlLib/Logging.h +++ b/IntelPresentMon/ControlLib/Logging.h @@ -3,7 +3,7 @@ #pragma once #include #include -#include "igcl_api.h" +#include "igcl/igcl_api.h" #include "../CommonUtilities/log/Log.h" namespace pwr::log diff --git a/IntelPresentMon/ControlLib/MetricUse.h b/IntelPresentMon/ControlLib/MetricUse.h deleted file mode 100644 index 39ea77c5..00000000 --- a/IntelPresentMon/ControlLib/MetricUse.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2026 Intel Corporation -// SPDX-License-Identifier: MIT -#pragma once - -#include "../CommonUtilities/Hash.h" -#include "../PresentMonAPI2/PresentMonAPI.h" -#include -#include -#include -#include -#include - -namespace pmon::svc -{ - struct MetricUse - { - PM_METRIC metricId; - uint32_t deviceId; - uint32_t arrayIdx; - - template - void serialize(A& ar) - { - ar(CEREAL_NVP(metricId), - CEREAL_NVP(deviceId), - CEREAL_NVP(arrayIdx)); - } - - bool operator==(const MetricUse& rhs) const - { - return metricId == rhs.metricId && - deviceId == rhs.deviceId && - arrayIdx == rhs.arrayIdx; - } - }; - - using DeviceMetricUse = std::unordered_map>; -} - -namespace std -{ - template<> - struct hash - { - size_t operator()(const pmon::svc::MetricUse& mu) const noexcept - { - const uint64_t devIdx = - (uint64_t(mu.deviceId) << 32) | uint64_t(mu.arrayIdx); - - using Under = std::underlying_type_t; - const Under mid = (Under)mu.metricId; - - return pmon::util::hash::DualHash(mid, devIdx); - } - }; -} diff --git a/IntelPresentMon/ControlLib/NvidiaPowerTelemetryAdapter.cpp b/IntelPresentMon/ControlLib/NvidiaPowerTelemetryAdapter.cpp deleted file mode 100644 index 24861179..00000000 --- a/IntelPresentMon/ControlLib/NvidiaPowerTelemetryAdapter.cpp +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#define NOMINMAX -#include -#include "NvidiaPowerTelemetryAdapter.h" -#include "Logging.h" -#include - - -namespace pwr::nv -{ - NvidiaPowerTelemetryAdapter::NvidiaPowerTelemetryAdapter( - uint32_t deviceId, - const NvapiWrapper* pNvapi, - const NvmlWrapper* pNvml, - NvPhysicalGpuHandle hGpuNvapi, - std::optional hGpuNvml) - : - PowerTelemetryAdapter(deviceId), - nvapi{ pNvapi }, - nvml{ pNvml }, - hNvapi{ hGpuNvapi }, - hNvml{ hGpuNvml } - { - char adapterName[NVAPI_SHORT_STRING_MAX]; - if (nvapi->Ok(nvapi->GPU_GetFullName(hGpuNvapi, adapterName))) - { - name = adapterName; - } - } - - - - uint64_t NvidiaPowerTelemetryAdapter::GetDedicatedVideoMemory() const noexcept { - uint64_t video_mem_size = 0; - nvmlMemory_t mem{}; - if (nvml->Ok(nvml->DeviceGetMemoryInfo(*hNvml, &mem))) { - // free and total might be swapped in nvml; accessing .free to get - // total - video_mem_size = uint64_t(mem.free); - } - return video_mem_size; - } - - double NvidiaPowerTelemetryAdapter::GetSustainedPowerLimit() const noexcept - { - unsigned int limitMw = 0; - if (nvml->Ok(nvml->DeviceGetPowerManagementLimit(*hNvml, &limitMw))) - { - return double(limitMw) / 1000.; - } - return 0.f; - } - - PresentMonPowerTelemetryInfo NvidiaPowerTelemetryAdapter::Sample() noexcept - { - LARGE_INTEGER qpc; - QueryPerformanceCounter(&qpc); - - PresentMonPowerTelemetryInfo info{ - .qpc = (uint64_t)qpc.QuadPart, - }; - - // nvapi-sourced telemetry - {// gpu and vram temperatures - NV_GPU_THERMAL_SETTINGS thermals = { - .version = NV_GPU_THERMAL_SETTINGS_VER_2 - }; - if (nvapi->Ok(nvapi->GPU_GetThermalSettings(hNvapi, NVAPI_THERMAL_TARGET_ALL, &thermals))) - { - // loop through all sensors, read those of interest into output struct - for (const auto& sensor : thermals.sensor) - { - // TODO: consider prioritizing sensor.controller == NVAPI_THERMAL_CONTROLLER_GPU_INTERNAL when multiple GPU thermals are present - if ((sensor.target == NVAPI_THERMAL_TARGET_GPU) && - (sensor.controller == NVAPI_THERMAL_CONTROLLER_GPU_INTERNAL)) { - info.gpu_temperature_c = (double)sensor.currentTemp; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_temperature); - } - else if (sensor.target == NVAPI_THERMAL_TARGET_MEMORY) - { - info.vram_temperature_c = (double)sensor.currentTemp; - SetTelemetryCapBit(GpuTelemetryCapBits::vram_temperature); - } - } - } - // TODO: consider logging failure (lower logging level perhaps) - } - - {// gpu and vram clock frequencies - NV_GPU_CLOCK_FREQUENCIES freqs{ - .version = NV_GPU_CLOCK_FREQUENCIES_VER_3 - }; - if (nvapi->Ok(nvapi->GPU_GetAllClockFrequencies(hNvapi, &freqs))) - { - if (const auto& gpuDomain = freqs.domain[NVAPI_GPU_PUBLIC_CLOCK_GRAPHICS]; - gpuDomain.bIsPresent) - { - info.gpu_frequency_mhz = double(gpuDomain.frequency) / 1000.; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_frequency); - } - if (const auto& vramDomain = freqs.domain[NVAPI_GPU_PUBLIC_CLOCK_MEMORY]; - vramDomain.bIsPresent) - { - info.vram_frequency_mhz = double(vramDomain.frequency) / 1000.; - SetTelemetryCapBit(GpuTelemetryCapBits::vram_frequency); - } - } - // TODO: consider logging failure (lower logging level perhaps) - } - - {// fan speed - NvU32 tach = 0; - if (nvapi->Ok(nvapi->GPU_GetTachReading(hNvapi, &tach))) - { - info.fan_speed_rpm[0] = double(tach); - SetTelemetryCapBit(GpuTelemetryCapBits::fan_speed_0); - } - // TODO: consider logging failure (lower logging level perhaps) - } - - {// gpu utilization - NV_GPU_DYNAMIC_PSTATES_INFO_EX pstates{ - .version = NV_GPU_DYNAMIC_PSTATES_INFO_EX_VER - }; - if (nvapi->Ok(nvapi->GPU_GetDynamicPstatesInfoEx(hNvapi, &pstates))) - { - if (const auto& domain = pstates.utilization[NVAPI_GPU_UTILIZATION_DOMAIN_GPU]; - domain.bIsPresent) - { - info.gpu_utilization = double(domain.percentage); - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_utilization); - } - if (const auto& domain = pstates.utilization[NVAPI_GPU_UTILIZATION_DOMAIN_VID]; - domain.bIsPresent) - { - info.gpu_media_utilization = double(domain.percentage); - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_media_utilization); - } - } - // TODO: consider logging failure (lower logging level perhaps) - } - - - // nvml-sourced telemetry (if we have a valid nvml handle) - if (*hNvml) - { - {// gpu power - unsigned int powerMw = 0; - if (nvml->Ok(nvml->DeviceGetPowerUsage(*hNvml, &powerMw))) - { - info.gpu_power_w = double(powerMw) / 1000.; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_power); - } - // TODO: consider logging failure (lower logging level perhaps) - } - - {// power limit - unsigned int limitMw = 0; - if (nvml->Ok(nvml->DeviceGetPowerManagementLimit(*hNvml, &limitMw))) - { - info.gpu_sustained_power_limit_w = double(limitMw) / 1000.; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_sustained_power_limit); - } - // TODO: consider logging failure (lower logging level perhaps) - } - - {// memory usage - nvmlMemory_t mem{}; - if (nvml->Ok(nvml->DeviceGetMemoryInfo(*hNvml, &mem))) - { - // free and total might be swapped in nvml; accessing .free to get total - info.gpu_mem_total_size_b = uint64_t(mem.free); - info.gpu_mem_used_b = uint64_t(mem.used); - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_mem_size); - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_mem_used); - } - // TODO: consider logging failure (lower logging level perhaps) - } - - {// temperature - if (!GetPowerTelemetryCapBits().test(static_cast(GpuTelemetryCapBits::gpu_temperature))|| - (useNvmlTemperature)) - { - unsigned int temp = 0; - if (nvml->Ok(nvml->DeviceGetTemperature(*hNvml, nvmlTemperatureSensors_t::NVML_TEMPERATURE_GPU, &temp))) - { - info.gpu_temperature_c = (double)temp; - SetTelemetryCapBit(GpuTelemetryCapBits::gpu_temperature); - useNvmlTemperature = true; - } - // TODO: consider logging failure (lower logging level perhaps) - } - } - } - - return info; - } - - PM_DEVICE_VENDOR NvidiaPowerTelemetryAdapter::GetVendor() const noexcept - { - return PM_DEVICE_VENDOR::PM_DEVICE_VENDOR_NVIDIA; - } - - std::string NvidiaPowerTelemetryAdapter::GetName() const noexcept - { - return name; - } -} diff --git a/IntelPresentMon/ControlLib/NvidiaPowerTelemetryAdapter.h b/IntelPresentMon/ControlLib/NvidiaPowerTelemetryAdapter.h deleted file mode 100644 index efe7297f..00000000 --- a/IntelPresentMon/ControlLib/NvidiaPowerTelemetryAdapter.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#pragma once -#include "PowerTelemetryAdapter.h" -#include -#include "NvapiWrapper.h" -#include "NvmlWrapper.h" - -namespace pwr::nv -{ - class NvidiaPowerTelemetryAdapter : public PowerTelemetryAdapter - { - public: - NvidiaPowerTelemetryAdapter( - uint32_t deviceId, - const NvapiWrapper* pNvapi, - const NvmlWrapper* pNvml, - NvPhysicalGpuHandle hGpuNvapi, - std::optional hGpuNvml); - PresentMonPowerTelemetryInfo Sample() noexcept override; - PM_DEVICE_VENDOR GetVendor() const noexcept override; - std::string GetName() const noexcept override; - uint64_t GetDedicatedVideoMemory() const noexcept override; - uint64_t GetVideoMemoryMaxBandwidth() const noexcept override { return 0; } - double GetSustainedPowerLimit() const noexcept override; - - private: - // data - const NvapiWrapper* nvapi; - const NvmlWrapper* nvml; - NvPhysicalGpuHandle hNvapi; - std::optional hNvml; - std::string name = "Unknown Adapter Name"; - bool useNvmlTemperature = false; - }; -} diff --git a/IntelPresentMon/ControlLib/NvidiaPowerTelemetryProvider.cpp b/IntelPresentMon/ControlLib/NvidiaPowerTelemetryProvider.cpp deleted file mode 100644 index 93f412bb..00000000 --- a/IntelPresentMon/ControlLib/NvidiaPowerTelemetryProvider.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#include "NvidiaPowerTelemetryProvider.h" -#include "NvidiaPowerTelemetryAdapter.h" -#include "Logging.h" -#include "SignatureComparison.h" - -namespace pwr::nv -{ - NvidiaPowerTelemetryProvider::NvidiaPowerTelemetryProvider(DeviceIdAllocator& allocator) - { - // enumerate nvapi gpu device handles - std::vector> nvapiHandlePairs; - { - std::vector nvapiHandles(32); - - // enumerate gpu handles - auto count = (NvU32)nvapiHandles.size(); - if (!nvapi.Ok(nvapi.EnumPhysicalGPUs(nvapiHandles.data(), &count))) - { - throw std::runtime_error{ "Failed to enumerate nvapi gpus" }; - } - // resize container to actual count of handles that were set - nvapiHandles.resize(size_t(count)); - // package handles together with their adapter signatures - for (auto& handle : nvapiHandles) - { - nvapiHandlePairs.emplace_back(handle, nvapi.GetAdapterSignature(handle)); - } - } - - // enumerate nvml gpu device handles - using NvmlHandlePair = std::pair; - std::vector nvmlHandlePairs; - { - std::vector nvmlHandles; - - // get number of devices - unsigned int count = 0; - if (!nvml.Ok(nvml.DeviceGetCount_v2(&count))) - { - throw std::runtime_error{ "Failed to get nvml device count" }; - } - - // get device handles by index from 0 to n_devices-1 - for (unsigned int i = 0; i < count; i++) - { - nvmlDevice_t handle; - if (nvml.Ok(nvml.DeviceGetHandleByIndex_v2(i, &handle))) - { - nvmlHandles.push_back(handle); - } - // TODO: else consider logging low severity error on fail - } - - // package handles together with their adapter signatures - for (auto& handle : nvmlHandles) - { - nvmlHandlePairs.emplace_back(handle, nvml.GetAdapterSignature(handle)); - } - } - - // create adaptor object for each api adapter handle pair - // lambda to factor out repeated code pattern adapter creation and insertion into container, with exception quelling - const auto TryCreateAddAdapter = [this, &allocator](NvPhysicalGpuHandle nvapiHandle, std::optional nvmlHandle) { - try { - adapterPtrs.push_back(std::make_shared( - allocator.Next(), &nvapi, &nvml, nvapiHandle, nvmlHandle - )); - } - catch (const std::exception& e) { TELE_ERR(e.what()); } - catch (...) { TELE_ERR("unknown error"); } - }; - // in the special case where there is only one handle for each api, we assume they match - if (nvapiHandlePairs.size() == 1 && nvmlHandlePairs.size() == 1) - { - TryCreateAddAdapter(nvapiHandlePairs.front().first, nvmlHandlePairs.front().first); - return; - } - // otherwise use signatures to greedy find nvml matches for each nvapi adapter handle - for (const auto nvapiHandlePair : nvapiHandlePairs) - { - // find first matching nvml handle - const auto i = std::ranges::find_if(nvmlHandlePairs, [&nvapiHandlePair](const NvmlHandlePair& nvmlPair) { - return nvapiHandlePair.second == nvmlPair.second; - }); - // create adapter object using both handles if we find a match - if (i != nvmlHandlePairs.end()) - { - TryCreateAddAdapter(nvapiHandlePair.first, i->first); - // remove nvml handle from list of candidates after creating - nvmlHandlePairs.erase(i); - } - else - { - // create adapter object using nvapi only - TryCreateAddAdapter(nvapiHandlePair.first, std::nullopt); - } - } - } - - const std::vector>& NvidiaPowerTelemetryProvider::GetAdapters() noexcept - { - return adapterPtrs; - } - - uint32_t NvidiaPowerTelemetryProvider::GetAdapterCount() const noexcept - { - return (uint32_t)adapterPtrs.size(); - } -} diff --git a/IntelPresentMon/ControlLib/NvidiaPowerTelemetryProvider.h b/IntelPresentMon/ControlLib/NvidiaPowerTelemetryProvider.h deleted file mode 100644 index a778b752..00000000 --- a/IntelPresentMon/ControlLib/NvidiaPowerTelemetryProvider.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#pragma once -#define NOMINMAX -#include -#include -#include -#include -#include -#include "PresentMonPowerTelemetry.h" -#include "PowerTelemetryProvider.h" -#include "NvapiWrapper.h" -#include "NvmlWrapper.h" -#include "DeviceIdAllocator.h" - -namespace pwr::nv -{ - class NvidiaPowerTelemetryProvider : public PowerTelemetryProvider - { - public: - explicit NvidiaPowerTelemetryProvider(DeviceIdAllocator& allocator); - const std::vector>& GetAdapters() noexcept override; - uint32_t GetAdapterCount() const noexcept override; - - private: - NvapiWrapper nvapi; - NvmlWrapper nvml; - std::vector> adapterPtrs; - }; -} diff --git a/IntelPresentMon/ControlLib/PowerTelemetryAdapter.cpp b/IntelPresentMon/ControlLib/PowerTelemetryAdapter.cpp deleted file mode 100644 index f50567f6..00000000 --- a/IntelPresentMon/ControlLib/PowerTelemetryAdapter.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "PowerTelemetryAdapter.h" -#include "Logging.h" -#include "../CommonUtilities/ref/WrapReflect.h" -#include "../CommonUtilities/ref/StaticReflection.h" -#include - - -namespace pwr -{ - using namespace std::literals; - using namespace pmon::util; - using v = ::pmon::util::log::V; - using ::pmon::util::log::GlobalPolicy; - - PowerTelemetryAdapter::PowerTelemetryAdapter(uint32_t deviceId) noexcept - : deviceId_{ deviceId } {} - - uint32_t PowerTelemetryAdapter::GetDeviceId() const noexcept - { - return deviceId_; - } - - void PowerTelemetryAdapter::SetTelemetryCapBit(GpuTelemetryCapBits telemetryCapBit) noexcept - { - if (GlobalPolicy::VCheck(v::tele_gpu)) { - if (!gpuTelemetryCapBits_.test(static_cast(telemetryCapBit))) { - pmlog_verb(v::tele_gpu)("Telemetry cap bit being set: "s + std::string(reflect::enum_name(telemetryCapBit))) - .pmwatch(GetName()); - } - } - gpuTelemetryCapBits_.set(static_cast(telemetryCapBit)); - } - PowerTelemetryAdapter::SetTelemetryCapBitset PowerTelemetryAdapter::GetPowerTelemetryCapBits() - { - pmlog_verb(v::tele_gpu)("Telemetry cap bits being retrieved").pmwatch(GetName()) - .pmwatch(ref::DumpEnumBitset(gpuTelemetryCapBits_)); - return gpuTelemetryCapBits_; - } - bool PowerTelemetryAdapter::HasTelemetryCapBit(GpuTelemetryCapBits bit) const - { - pmlog_verb(v::tele_gpu)("Telemetry cap bit being retrieved: "s + std::string(reflect::enum_name(bit))) - .pmwatch(GetName()).pmwatch(gpuTelemetryCapBits_.test(size_t(bit))); - return gpuTelemetryCapBits_.test(size_t(bit)); - } -} diff --git a/IntelPresentMon/ControlLib/PowerTelemetryAdapter.h b/IntelPresentMon/ControlLib/PowerTelemetryAdapter.h deleted file mode 100644 index c2157f52..00000000 --- a/IntelPresentMon/ControlLib/PowerTelemetryAdapter.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#pragma once - -#include -#include -#include -#include -#include "PresentMonPowerTelemetry.h" -#include "../PresentMonAPI2/PresentMonAPI.h" - -namespace pwr -{ - class PowerTelemetryAdapter - { - public: - // types - using SetTelemetryCapBitset = std::bitset(GpuTelemetryCapBits::gpu_telemetry_count)>; - // functions - virtual ~PowerTelemetryAdapter() = default; - virtual PresentMonPowerTelemetryInfo Sample() noexcept = 0; - virtual PM_DEVICE_VENDOR GetVendor() const noexcept = 0; - virtual std::string GetName() const noexcept = 0; - virtual uint64_t GetDedicatedVideoMemory() const noexcept = 0; - virtual uint64_t GetVideoMemoryMaxBandwidth() const noexcept = 0; - virtual double GetSustainedPowerLimit() const noexcept = 0; - virtual uint64_t GetAdapterId() const noexcept { return 0; } - uint32_t GetDeviceId() const noexcept; - void SetTelemetryCapBit(GpuTelemetryCapBits telemetryCapBit) noexcept; - SetTelemetryCapBitset GetPowerTelemetryCapBits(); - bool HasTelemetryCapBit(GpuTelemetryCapBits bit) const; - protected: - explicit PowerTelemetryAdapter(uint32_t deviceId) noexcept; - - private: - // data - SetTelemetryCapBitset gpuTelemetryCapBits_{}; - const uint32_t deviceId_ = 0; - }; -} diff --git a/IntelPresentMon/ControlLib/PowerTelemetryProvider.h b/IntelPresentMon/ControlLib/PowerTelemetryProvider.h deleted file mode 100644 index 34b8d84b..00000000 --- a/IntelPresentMon/ControlLib/PowerTelemetryProvider.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#pragma once -#include -#include -#include -#include -#include "PresentMonPowerTelemetry.h" -#include "PowerTelemetryAdapter.h" - -namespace pwr -{ - class PowerTelemetryProvider - { - public: - virtual ~PowerTelemetryProvider() = default; - virtual const std::vector>& GetAdapters() noexcept = 0; - virtual uint32_t GetAdapterCount() const noexcept = 0; - }; -} \ No newline at end of file diff --git a/IntelPresentMon/ControlLib/PowerTelemetryProviderFactory.cpp b/IntelPresentMon/ControlLib/PowerTelemetryProviderFactory.cpp deleted file mode 100644 index eec1143c..00000000 --- a/IntelPresentMon/ControlLib/PowerTelemetryProviderFactory.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#include "PowerTelemetryProviderFactory.h" -#include "IntelPowerTelemetryProvider.h" -#include "NvidiaPowerTelemetryProvider.h" -#include "AmdPowerTelemetryProvider.h" - -namespace pwr -{ - std::unique_ptr PowerTelemetryProviderFactory::Make(PM_DEVICE_VENDOR vendor, DeviceIdAllocator& allocator) - { - switch (vendor) { - case PM_DEVICE_VENDOR_INTEL: return std::make_unique(allocator); - case PM_DEVICE_VENDOR_NVIDIA: return std::make_unique(allocator); - case PM_DEVICE_VENDOR_AMD: return std::make_unique(allocator); - } - return {}; - } -} diff --git a/IntelPresentMon/ControlLib/PowerTelemetryProviderFactory.h b/IntelPresentMon/ControlLib/PowerTelemetryProviderFactory.h deleted file mode 100644 index 37fa9d36..00000000 --- a/IntelPresentMon/ControlLib/PowerTelemetryProviderFactory.h +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#pragma once -#include "PowerTelemetryProvider.h" -#include "DeviceIdAllocator.h" -#include "../PresentMonAPI2/PresentMonAPI.h" -#include - -namespace pwr -{ - class PowerTelemetryProviderFactory - { - public: - static std::unique_ptr Make(PM_DEVICE_VENDOR vendor, DeviceIdAllocator& allocator); - }; -} diff --git a/IntelPresentMon/ControlLib/PresentMonPowerTelemetry.h b/IntelPresentMon/ControlLib/PresentMonPowerTelemetry.h deleted file mode 100644 index cceb1fc6..00000000 --- a/IntelPresentMon/ControlLib/PresentMonPowerTelemetry.h +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#pragma once -#include -#include -#include - -enum class PresentMonPsuType -{ - None, - Pcie, - Pin6, - Pin8, -}; - -struct PresentMonPsuPowerTelemetryInfo { - PresentMonPsuType psu_type; - double psu_power; - double psu_voltage; -}; - -struct PresentMonPowerTelemetryInfo { - uint64_t qpc; - - double time_stamp; - - double gpu_power_w; - double gpu_sustained_power_limit_w; - double gpu_voltage_v; - double gpu_frequency_mhz; - double gpu_temperature_c; - double gpu_utilization; - double gpu_render_compute_utilization; - double gpu_media_utilization; - double gpu_effective_frequency_mhz; - double gpu_voltage_regulator_temperature_c; - double gpu_mem_effective_bandwidth_gbps; - double gpu_overvoltage_percent; - double gpu_temperature_percent; - double gpu_power_percent; - double gpu_card_power_w; - - double vram_power_w; - double vram_voltage_v; - double vram_frequency_mhz; - double vram_effective_frequency_gbps; - double vram_temperature_c; - - std::array fan_speed_rpm; - std::array max_fan_speed_rpm; - std::array psu; - - // GPU memory state - uint64_t gpu_mem_total_size_b; - uint64_t gpu_mem_used_b; - - // GPU memory bandwidth - uint64_t gpu_mem_max_bandwidth_bps; - double gpu_mem_write_bandwidth_bps; - double gpu_mem_read_bandwidth_bps; - - // Throttling flags - bool gpu_power_limited; - bool gpu_temperature_limited; - bool gpu_current_limited; - bool gpu_voltage_limited; - bool gpu_utilization_limited; - - bool vram_power_limited; - bool vram_temperature_limited; - bool vram_current_limited; - bool vram_voltage_limited; - bool vram_utilization_limited; -}; - -enum class GpuTelemetryCapBits { - time_stamp, - gpu_power, - gpu_sustained_power_limit, - gpu_voltage, - gpu_frequency, - gpu_temperature, - gpu_utilization, - gpu_render_compute_utilization, - gpu_media_utilization, - vram_power, - vram_voltage, - vram_frequency, - vram_effective_frequency, - vram_temperature, - fan_speed_0, - fan_speed_1, - fan_speed_2, - fan_speed_3, - fan_speed_4, - psu_info_0, - psu_info_1, - psu_info_2, - psu_info_3, - psu_info_4, - gpu_mem_size, - gpu_mem_used, - gpu_mem_max_bandwidth, - gpu_mem_write_bandwidth, - gpu_mem_read_bandwidth, - gpu_power_limited, - gpu_temperature_limited, - gpu_current_limited, - gpu_voltage_limited, - gpu_utilization_limited, - vram_power_limited, - vram_temperature_limited, - vram_current_limited, - vram_voltage_limited, - vram_utilization_limited, - gpu_effective_frequency, - gpu_voltage_regulator_temperature, - gpu_mem_effective_bandwidth, - gpu_overvoltage_percent, - gpu_temperature_percent, - gpu_power_percent, - max_fan_speed_0, - max_fan_speed_1, - max_fan_speed_2, - max_fan_speed_3, - max_fan_speed_4, - gpu_card_power, - gpu_telemetry_count, -}; - -using GpuTelemetryBitset = std::bitset(GpuTelemetryCapBits::gpu_telemetry_count)>; \ No newline at end of file diff --git a/IntelPresentMon/ControlLib/SignatureComparison.cpp b/IntelPresentMon/ControlLib/SignatureComparison.cpp deleted file mode 100644 index 1cb2d709..00000000 --- a/IntelPresentMon/ControlLib/SignatureComparison.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#include "SignatureComparison.h" -#include "NvapiWrapper.h" -#include "NvmlWrapper.h" - -namespace pwr::nv -{ - bool operator==(const NvapiAdapterSignature& nvapi, const NvmlAdapterSignature& nvml) noexcept - { - // pci identifier test has priority - if (nvapi.deviceId == nvml.pciDeviceId && nvapi.subSystemId == nvml.pciSubSystemId) - { - return true; - } - // if pci identifier test fails, fallback to nvml domain/bus/function test - if (nvapi.busId == nvml.busIdBus) - { - return true; - } - return false; - } -} \ No newline at end of file diff --git a/IntelPresentMon/ControlLib/SignatureComparison.h b/IntelPresentMon/ControlLib/SignatureComparison.h deleted file mode 100644 index 55072d32..00000000 --- a/IntelPresentMon/ControlLib/SignatureComparison.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#pragma once -#include - -namespace pwr::nv -{ - struct NvapiAdapterSignature; - struct NvmlAdapterSignature; - - bool operator==(const NvapiAdapterSignature& nvapi, const NvmlAdapterSignature& nvml) noexcept; -} \ No newline at end of file diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp index b26d343d..de19a2de 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp @@ -51,6 +51,116 @@ namespace pmon::tel BuildLogicalDevicesAndRoutes_(); } + std::optional TelemetryCoordinator::GetCpuInfo() const + { + const auto iLogicalDevice = logicalDevicesById_.find(ipc::kSystemDeviceId); + if (iLogicalDevice == logicalDevicesById_.end()) { + return std::nullopt; + } + + const auto requestQpc = util::GetCurrentTimestamp(); + const auto& logicalDevice = iLogicalDevice->second; + + CpuInfo cpuInfo{}; + cpuInfo.name = "UNKNOWN_CPU"; + + bool haveFingerprint = false; + const auto fingerprint = ResolveLogicalDeviceFingerprint_(logicalDevice, haveFingerprint); + if (haveFingerprint) { + cpuInfo.vendor = fingerprint.vendor; + if (!fingerprint.deviceName.empty()) { + cpuInfo.name = fingerprint.deviceName; + } + } + else { + pmlog_warn("No provider-device fingerprint available for CPU enumeration"); + } + + if (logicalDevice.routes.contains(PM_METRIC_CPU_POWER_LIMIT)) { + try { + const auto value = PollMetricForRoute_(logicalDevice, PM_METRIC_CPU_POWER_LIMIT, 0, requestQpc); + if (const auto pVal = std::get_if(&value)) { + cpuInfo.cpuPowerLimit = *pVal; + } + else { + throw util::Except<>("Type mismatch while enumerating CPU static metric"); + } + } + catch (...) { + pmlog_error(util::ReportException("CPU static metric query failed")) + .pmwatch((int)PM_METRIC_CPU_POWER_LIMIT); + } + } + + return cpuInfo; + } + + std::vector TelemetryCoordinator::EnumerateAdapters() const + { + const auto requestQpc = util::GetCurrentTimestamp(); + std::vector adapters; + adapters.reserve(logicalDevicesById_.size()); + + for (const auto& [logicalDeviceId, logicalDevice] : logicalDevicesById_) { + if (logicalDeviceId == ipc::kSystemDeviceId) { + continue; + } + + AdapterInfo adapter{}; + adapter.id = logicalDeviceId; + adapter.name = "UNKNOWN_GPU"; + + bool haveFingerprint = false; + const auto fingerprint = ResolveLogicalDeviceFingerprint_(logicalDevice, haveFingerprint); + if (haveFingerprint) { + adapter.vendor = fingerprint.vendor; + if (!fingerprint.deviceName.empty()) { + adapter.name = fingerprint.deviceName; + } + } + else { + pmlog_warn("No provider-device fingerprint available for adapter enumeration") + .pmwatch(logicalDeviceId); + } + + const auto populateStaticMetric = [&](PM_METRIC metricId, T& destination) { + if (!logicalDevice.routes.contains(metricId)) { + return; + } + + try { + const auto value = PollMetricForRoute_(logicalDevice, metricId, 0, requestQpc); + if (const auto pVal = std::get_if(&value)) { + destination = *pVal; + } + else { + throw util::Except<>("Type mismatch while enumerating adapter static metric"); + } + } + catch (...) { + pmlog_error(util::ReportException("Adapter static metric query failed")) + .pmwatch(logicalDeviceId) + .pmwatch((int)metricId); + } + }; + + populateStaticMetric(PM_METRIC_GPU_SUSTAINED_POWER_LIMIT, adapter.gpuSustainedPowerLimit); + populateStaticMetric(PM_METRIC_GPU_MEM_SIZE, adapter.gpuMemorySize); + populateStaticMetric(PM_METRIC_GPU_MEM_MAX_BANDWIDTH, adapter.gpuMemoryMaxBandwidth); + + adapters.push_back(std::move(adapter)); + } + + std::sort(adapters.begin(), adapters.end(), [](const AdapterInfo& lhs, const AdapterInfo& rhs) { + if (lhs.gpuMemorySize != rhs.gpuMemorySize) { + return lhs.gpuMemorySize > rhs.gpuMemorySize; + } + return lhs.id < rhs.id; + }); + + return adapters; + } + void TelemetryCoordinator::RegisterDevicesToIpc(ipc::ServiceComms& comms) const { bool cpuRegistered = false; diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.h b/IntelPresentMon/ControlLib/TelemetryCoordinator.h index 5d384e64..bf366fec 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.h +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.h @@ -2,9 +2,11 @@ // SPDX-License-Identifier: MIT #pragma once -#include "MetricUse.h" +#include "../PresentMonService/MetricUse.h" #include "TelemetryProvider.h" #include +#include +#include #include #include @@ -19,9 +21,30 @@ namespace pmon::tel class TelemetryCoordinator { public: + struct CpuInfo + { + PM_DEVICE_VENDOR vendor = PM_DEVICE_VENDOR_UNKNOWN; + std::string name{}; + double cpuPowerLimit = 0.0; + }; + + struct AdapterInfo + { + uint32_t id = 0; + PM_DEVICE_VENDOR vendor = PM_DEVICE_VENDOR_UNKNOWN; + std::string name{}; + double gpuSustainedPowerLimit = 0.0; + uint64_t gpuMemorySize = 0; + uint64_t gpuMemoryMaxBandwidth = 0; + }; + // Constructs all known concrete providers, correlates logical devices, // and builds metric polling routes. TelemetryCoordinator(); + // Returns system CPU static identity and routed static telemetry when present. + std::optional GetCpuInfo() const; + // Returns GPU adapter identity and routed static telemetry for legacy service enumeration. + std::vector EnumerateAdapters() const; // Registers logical CPU/GPU devices and per-device routed capabilities with IPC. void RegisterDevicesToIpc(ipc::ServiceComms& comms) const; // Populates available static data into IPC device stores. diff --git a/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h b/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h index d6ec6a9d..0ad74b64 100644 --- a/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h +++ b/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h @@ -15,7 +15,7 @@ namespace pmon::tel PM_DEVICE_VENDOR vendor = PM_DEVICE_VENDOR_UNKNOWN; std::string deviceName; - // Correlation fields aligned with NVIDIA legacy matching. + // Correlation fields aligned with NVIDIA matching. std::optional pciDeviceId; std::optional pciSubSystemId; std::optional pciBusId; diff --git a/IntelPresentMon/ControlLib/WmiCpu.cpp b/IntelPresentMon/ControlLib/WmiCpu.cpp deleted file mode 100644 index 34edc596..00000000 --- a/IntelPresentMon/ControlLib/WmiCpu.cpp +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#include -#include "WmiCpu.h" - -#include "../CommonUtilities/log/GlogShim.h" - -namespace pwr::cpu::wmi { - -std::wstring kProcessorFrequency = - L"\\Processor Information(_Total)\\Processor Frequency"; -std::wstring kProcessorPerformance = - L"\\Processor Information(_Total)\\% Processor Performance"; -std::wstring kProcessorIdleTime = L"\\Processor(_Total)\\% Idle Time"; - -WmiCpu::WmiCpu() { - HQUERY temp_query = nullptr; - if (const auto result = PdhOpenQuery(NULL, NULL, &temp_query); - result != ERROR_SUCCESS) { - throw std::runtime_error{ - std::format("PdhOpenQuery failed. Result:{}", result).c_str()}; - } - query_.reset(temp_query); - - if (const auto result = - PdhAddEnglishCounterW(query_.get(), kProcessorFrequency.c_str(), 0, - &processor_frequency_counter_); - result != ERROR_SUCCESS) { - LOG(INFO) << "PdhAddEnglishCounter failed when adding processor frequency counter. Result:" - << result << std::endl; - } - - if (const auto result = - PdhAddEnglishCounterW(query_.get(), kProcessorPerformance.c_str(), - 0, &processor_performance_counter_); - result != ERROR_SUCCESS) { - LOG(INFO) << "PdhAddEnglishCounter failed when adding processor performance counter. Result:" - << result << std::endl; - } - - if (const auto result = PdhAddEnglishCounterW(query_.get(), kProcessorIdleTime.c_str(), 0, - &processor_idle_time_counter_); - result != ERROR_SUCCESS) { - LOG(INFO) << "PdhAddEnglishCounter failed when adding processor time counter. Result:" - << result << std::endl; - } - - // Most counters require two sample values to display a formatted value. - // PDH stores the current sample value and the previously collected - // sample value. This call retrieves the first value that will be used - // by PdhGetFormattedCounterValue in the next data collection. - if (const auto result = PdhCollectQueryData(query_.get()); - result != ERROR_SUCCESS) { - throw std::runtime_error{ - std::format("PdhCollectQueryData failed. Result: {}", result).c_str()}; - } - - // WMI specifies that it should not be sampled faster than once every - // second. We however allow the user to specify the sample rate for - // telemetry. Through testing it was observed that allowing a - // sample rate of faster than one second will cause the CPU utilization - // number to become inaccurate. Because of this we will impose - // a one second wait for WMI sampling. - - // Grab the current QPC frequency which returns the current performance- - // counter frequency in counts per SECOND. - QueryPerformanceFrequency(&frequency_); - // Now grab the current value of the performance counter - QueryPerformanceCounter(&next_sample_qpc_); - // To calculate the next time we should sample take the just sampled - // performance counter and the frequency. - // next_sample_qpc_.QuadPart += frequency_.QuadPart; -} - - -CpuTelemetryInfo WmiCpu::Sample() noexcept { - DWORD counter_type; - - LARGE_INTEGER qpc; - QueryPerformanceCounter(&qpc); - const bool should_collect = qpc.QuadPart >= next_sample_qpc_.QuadPart; - - CpuTelemetryInfo info{ - .qpc = (uint64_t)qpc.QuadPart, - }; - - if (should_collect) { - if (const auto result = PdhCollectQueryData(query_.get()); - result != ERROR_SUCCESS) { - LOG(INFO) << "PdhCollectQueryData failed. Result:" << result << std::endl; - } else { - // Update the next sample qpc based on the current sample qpc - // and adding in the frequency - next_sample_qpc_.QuadPart = qpc.QuadPart + frequency_.QuadPart; - } - } - - // Sample cpu clock. This is an approximation using the frequency and then - // the current percentage. - PDH_FMT_COUNTERVALUE counter_value; - { - if (const auto result = PdhGetFormattedCounterValue( - processor_frequency_counter_, PDH_FMT_DOUBLE, &counter_type, - &counter_value); - result == ERROR_SUCCESS) { - info.cpu_frequency = counter_value.doubleValue; - - if (const auto result2 = PdhGetFormattedCounterValue( - processor_performance_counter_, PDH_FMT_DOUBLE, &counter_type, - &counter_value); - result2 == ERROR_SUCCESS) { - info.cpu_frequency = - info.cpu_frequency * (counter_value.doubleValue / 100.); - SetTelemetryCapBit(CpuTelemetryCapBits::cpu_frequency); - } - } - } - - // Sample cpu idle time, and compute cpu utilization using it (Windows 11 Fix) - // - // Beginning with Windows 11 22H2, the performance counters for CPU idle time - // in SystemProcessorPerformanceInformation are broken and statistics derived - // from those counters will always indicate single-digit cpu utilization %. - // - // Idle time reported in SystemProcessorIdleInformation is still consistent on - // all versions of Windows, as well as WMI provisioned "Processor\% Idle Time". - // - // To measure CPU utilization accurately on all systems, it must be calculated: - // - // 100.0 - "Processor(_Total)\% Idle Time" - { - if (const auto result = - PdhGetFormattedCounterValue(processor_idle_time_counter_, PDH_FMT_DOUBLE, - &counter_type, &counter_value); - result == ERROR_SUCCESS) { - info.cpu_utilization = 100.0 - counter_value.doubleValue; - SetTelemetryCapBit(CpuTelemetryCapBits::cpu_utilization); - } - } - - return info; -} - -} diff --git a/IntelPresentMon/ControlLib/WmiCpu.h b/IntelPresentMon/ControlLib/WmiCpu.h deleted file mode 100644 index 1fb67b42..00000000 --- a/IntelPresentMon/ControlLib/WmiCpu.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#pragma once -#define NOMINMAX -#include -#include -#include "CpuTelemetry.h" - -namespace pwr::cpu::wmi { - -struct PDHQueryDeleter { - void operator()(PDH_HQUERY query) const { PdhCloseQuery(query); } -}; - -class WmiCpu : public CpuTelemetry { - public: - WmiCpu(); - CpuTelemetryInfo Sample() noexcept override; - // types - class NonGraphicsDeviceException : public std::exception {}; - - private: - // data - std::unique_ptr, PDHQueryDeleter> query_; - HCOUNTER processor_frequency_counter_; - HCOUNTER processor_performance_counter_; - HCOUNTER processor_idle_time_counter_; - LARGE_INTEGER next_sample_qpc_ = {}; - LARGE_INTEGER frequency_ = {}; - std::string cpu_name_; -}; - -} // namespace pwr::cpu::wmi diff --git a/IntelPresentMon/ControlLib/Adl2Wrapper.cpp b/IntelPresentMon/ControlLib/adl/Adl2Wrapper.cpp similarity index 92% rename from IntelPresentMon/ControlLib/Adl2Wrapper.cpp rename to IntelPresentMon/ControlLib/adl/Adl2Wrapper.cpp index 72e664d9..d00c73b3 100644 --- a/IntelPresentMon/ControlLib/Adl2Wrapper.cpp +++ b/IntelPresentMon/ControlLib/adl/Adl2Wrapper.cpp @@ -1,8 +1,8 @@ -// Copyright (C) 2022 Intel Corporation +// Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: MIT #include "Adl2Wrapper.h" -namespace pwr::amd { +namespace pmon::tel::adl { void* __stdcall ADL_Main_Memory_Alloc(int iSize) { void* lpBuffer = malloc(iSize); @@ -33,7 +33,7 @@ namespace pwr::amd { // Initialize ADL2. The second parameter is 1, which means: // retrieve adapter information only for adapters that are physically // present and enabled in the system - if (!Ok(adl2_main_control_create_ptr(pwr::amd::ADL_Main_Memory_Alloc, 1, + if (!Ok(adl2_main_control_create_ptr(ADL_Main_Memory_Alloc, 1, &adl_context_))) { throw std::runtime_error{"adl2 init call failed"}; } @@ -56,4 +56,4 @@ namespace pwr::amd { } AMD_ADL2_ENDPOINT_LIST #undef X_ -} // namespace pwr::amd \ No newline at end of file +} // namespace pmon::tel::adl diff --git a/IntelPresentMon/ControlLib/Adl2Wrapper.h b/IntelPresentMon/ControlLib/adl/Adl2Wrapper.h similarity index 97% rename from IntelPresentMon/ControlLib/Adl2Wrapper.h rename to IntelPresentMon/ControlLib/adl/Adl2Wrapper.h index 8657ff1e..fe3f7d6e 100644 --- a/IntelPresentMon/ControlLib/Adl2Wrapper.h +++ b/IntelPresentMon/ControlLib/adl/Adl2Wrapper.h @@ -1,9 +1,9 @@ -// Copyright (C) 2022 Intel Corporation +// Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: MIT #pragma once #include "adl_sdk.h" -#include "DllModule.h" -#include "MacroHelpers.h" +#include "../DllModule.h" +#include "../MacroHelpers.h" // goals: single source of truth, automatic id lookup, parameter names in @@ -67,7 +67,7 @@ X_(OverdriveN_FanControl_Get, int, iAdapterIndex, ADLODNFanControl*, \ lpOdFanControl) -namespace pwr::amd { +namespace pmon::tel::adl { class Adl2Wrapper { public: Adl2Wrapper(); @@ -91,4 +91,4 @@ namespace pwr::amd { // Private endpoint pointer to shutdown ADL2 int (*ADL2_Main_Control_Destroy_ptr_)(ADL_CONTEXT_HANDLE) = nullptr; }; -} // namespace pwr::amd \ No newline at end of file +} // namespace pmon::tel::adl diff --git a/IntelPresentMon/ControlLib/adl/AmdTelemetryProvider.cpp b/IntelPresentMon/ControlLib/adl/AmdTelemetryProvider.cpp index b35b7a5e..a9800382 100644 --- a/IntelPresentMon/ControlLib/adl/AmdTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/adl/AmdTelemetryProvider.cpp @@ -30,7 +30,7 @@ namespace pmon::tel::adl AmdTelemetryProvider::AmdTelemetryProvider() { try { - pAdl_ = std::make_unique(); + pAdl_ = std::make_unique(); } catch (const TelemetrySubsystemAbsent&) { throw; @@ -42,7 +42,7 @@ namespace pmon::tel::adl int adapterCount = 0; const auto countResult = pAdl_->Adapter_NumberOfAdapters_Get(&adapterCount); - if (!pwr::amd::Adl2Wrapper::Ok(countResult)) { + if (!Adl2Wrapper::Ok(countResult)) { pmlog_error("ADL2_Adapter_NumberOfAdapters_Get failed").code(countResult); throw Except<>("ADL adapter count query failed"); } @@ -59,7 +59,7 @@ namespace pmon::tel::adl const auto infoResult = pAdl_->Adapter_AdapterInfo_Get( adapterInfos.data(), (int)(adapterInfos.size() * sizeof(AdapterInfo))); - if (!pwr::amd::Adl2Wrapper::Ok(infoResult)) { + if (!Adl2Wrapper::Ok(infoResult)) { pmlog_error("ADL2_Adapter_AdapterInfo_Get failed").code(infoResult); throw Except<>("ADL adapter info query failed"); } @@ -290,7 +290,7 @@ namespace pmon::tel::adl &overdriveSupported, &overdriveEnabled, &overdriveVersion); - if (!pwr::amd::Adl2Wrapper::Ok(capsResult)) { + if (!Adl2Wrapper::Ok(capsResult)) { pmlog_warn("ADL2_Overdrive_Caps failed").code(capsResult) .pmwatch(device.providerDeviceId) .pmwatch(device.fingerprint.deviceName); @@ -332,7 +332,7 @@ namespace pmon::tel::adl device.adlAdapterIndex, thermalControllerIndex, &thermalInfo); - if (!pwr::amd::Adl2Wrapper::Ok(result)) { + if (!Adl2Wrapper::Ok(result)) { if (result != ADL_ERR_INVALID_CONTROLLER_IDX && result != ADL_ERR) { pmlog_warn("ADL2_Overdrive5_ThermalDevices_Enum failed").code(result) .pmwatch(device.providerDeviceId) @@ -426,7 +426,7 @@ namespace pmon::tel::adl device.memoryInfoQueried = true; ADLMemoryInfoX4 memoryInfo{}; const auto result = pAdl_->Adapter_MemoryInfoX4_Get(device.adlAdapterIndex, &memoryInfo); - if (!pwr::amd::Adl2Wrapper::Ok(result)) { + if (!Adl2Wrapper::Ok(result)) { pmlog_warn("ADL2_Adapter_MemoryInfoX4_Get failed").code(result) .pmwatch(device.providerDeviceId) .pmwatch(device.fingerprint.deviceName); @@ -452,7 +452,7 @@ namespace pmon::tel::adl auto result = pAdl_->Overdrive5_PowerControl_Caps( device.adlAdapterIndex, &powerControlSupported); - if (!pwr::amd::Adl2Wrapper::Ok(result)) { + if (!Adl2Wrapper::Ok(result)) { pmlog_warn("ADL2_Overdrive5_PowerControl_Caps failed").code(result) .pmwatch(device.providerDeviceId) .pmwatch(device.fingerprint.deviceName); @@ -468,7 +468,7 @@ namespace pmon::tel::adl device.adlAdapterIndex, &powerControlCurrent, &powerControlDefault); - if (!pwr::amd::Adl2Wrapper::Ok(result)) { + if (!Adl2Wrapper::Ok(result)) { pmlog_warn("ADL2_Overdrive5_PowerControl_Get failed").code(result) .pmwatch(device.providerDeviceId) .pmwatch(device.fingerprint.deviceName); @@ -485,7 +485,7 @@ namespace pmon::tel::adl auto result = pAdl_->Overdrive6_PowerControl_Caps( device.adlAdapterIndex, &powerControlSupported); - if (!pwr::amd::Adl2Wrapper::Ok(result)) { + if (!Adl2Wrapper::Ok(result)) { pmlog_warn("ADL2_Overdrive6_PowerControl_Caps failed").code(result) .pmwatch(device.providerDeviceId) .pmwatch(device.fingerprint.deviceName); @@ -501,7 +501,7 @@ namespace pmon::tel::adl device.adlAdapterIndex, &powerControlCurrent, &powerControlDefault); - if (!pwr::amd::Adl2Wrapper::Ok(result)) { + if (!Adl2Wrapper::Ok(result)) { pmlog_warn("ADL2_Overdrive6_PowerControl_Get failed").code(result) .pmwatch(device.providerDeviceId) .pmwatch(device.fingerprint.deviceName); @@ -532,7 +532,7 @@ namespace pmon::tel::adl int vramUsageMb = 0; const auto vramUsageResult = pAdl_->Adapter_VRAMUsage_Get(device.adlAdapterIndex, &vramUsageMb); - if (pwr::amd::Adl2Wrapper::Ok(vramUsageResult)) { + if (Adl2Wrapper::Ok(vramUsageResult)) { snapshot.hasGpuMemUsed = true; snapshot.gpuMemUsedBytes = (uint64_t)vramUsageMb * 1000000ull; } @@ -576,7 +576,7 @@ namespace pmon::tel::adl device.adlAdapterIndex, thermalControllerIndex, &temperature); - if (pwr::amd::Adl2Wrapper::Ok(tempResult)) { + if (Adl2Wrapper::Ok(tempResult)) { if (!snapshot.hasGpuTemperature) { snapshot.gpuTemperatureC = (double)temperature.iTemperature / 1000.0; snapshot.hasGpuTemperature = true; @@ -594,7 +594,7 @@ namespace pmon::tel::adl device.adlAdapterIndex, thermalControllerIndex, &fanInfo); - if (!pwr::amd::Adl2Wrapper::Ok(fanInfoResult)) { + if (!Adl2Wrapper::Ok(fanInfoResult)) { pmlog_warn("ADL2_Overdrive5_FanSpeedInfo_Get failed").code(fanInfoResult).every(std::chrono::seconds{ 60 }) .pmwatch(device.providerDeviceId) .pmwatch(device.fingerprint.deviceName) @@ -611,7 +611,7 @@ namespace pmon::tel::adl device.adlAdapterIndex, thermalControllerIndex, &fanValue); - if (pwr::amd::Adl2Wrapper::Ok(fanResult)) { + if (Adl2Wrapper::Ok(fanResult)) { snapshot.fanSpeedsRpm.push_back((double)fanValue.iFanSpeed); } else { @@ -631,7 +631,7 @@ namespace pmon::tel::adl device.adlAdapterIndex, thermalControllerIndex, &fanValue); - if (pwr::amd::Adl2Wrapper::Ok(fanResult)) { + if (Adl2Wrapper::Ok(fanResult)) { snapshot.fanSpeedRatios.push_back((double)fanValue.iFanSpeed / 100.0); } else { @@ -647,7 +647,7 @@ namespace pmon::tel::adl const auto activityResult = pAdl_->Overdrive5_CurrentActivity_Get( device.adlAdapterIndex, &activity); - if (pwr::amd::Adl2Wrapper::Ok(activityResult)) { + if (Adl2Wrapper::Ok(activityResult)) { snapshot.gpuUtilizationPercent = (double)activity.iActivityPercent; snapshot.hasGpuUtilization = true; @@ -675,11 +675,11 @@ namespace pmon::tel::adl const auto thermalCapsResult = pAdl_->Overdrive6_ThermalController_Caps( device.adlAdapterIndex, &thermalCaps); - if (pwr::amd::Adl2Wrapper::Ok(thermalCapsResult)) { + if (Adl2Wrapper::Ok(thermalCapsResult)) { if (HasFlag_(thermalCaps.iCapabilities, ADL_OD6_TCCAPS_THERMAL_CONTROLLER)) { int temperature = 0; const auto tempResult = pAdl_->Overdrive6_Temperature_Get(device.adlAdapterIndex, &temperature); - if (pwr::amd::Adl2Wrapper::Ok(tempResult)) { + if (Adl2Wrapper::Ok(tempResult)) { snapshot.gpuTemperatureC = (double)temperature / 1000.0; snapshot.hasGpuTemperature = true; } @@ -692,7 +692,7 @@ namespace pmon::tel::adl ADLOD6FanSpeedInfo fanInfo{}; const auto fanResult = pAdl_->Overdrive6_FanSpeed_Get(device.adlAdapterIndex, &fanInfo); - if (pwr::amd::Adl2Wrapper::Ok(fanResult)) { + if (Adl2Wrapper::Ok(fanResult)) { if (HasFlag_(fanInfo.iSpeedType, ADL_OD6_FANSPEED_TYPE_RPM)) { snapshot.fanSpeedsRpm.push_back((double)fanInfo.iFanSpeedRPM); } @@ -714,7 +714,7 @@ namespace pmon::tel::adl ADLOD6CurrentStatus currentStatus{}; const auto currentStatusResult = pAdl_->Overdrive6_CurrentStatus_Get(device.adlAdapterIndex, ¤tStatus); - if (pwr::amd::Adl2Wrapper::Ok(currentStatusResult)) { + if (Adl2Wrapper::Ok(currentStatusResult)) { snapshot.gpuFrequencyMhz = (double)currentStatus.iEngineClock / 100.0; snapshot.hasGpuFrequency = true; @@ -723,7 +723,7 @@ namespace pmon::tel::adl ADLOD6Capabilities capabilities{}; const auto capResult = pAdl_->Overdrive6_Capabilities_Get(device.adlAdapterIndex, &capabilities); - if (pwr::amd::Adl2Wrapper::Ok(capResult)) { + if (Adl2Wrapper::Ok(capResult)) { if (HasFlag_(capabilities.iCapabilities, ADL_OD6_CAPABILITY_GPU_ACTIVITY_MONITOR)) { snapshot.gpuUtilizationPercent = (double)currentStatus.iActivityPercent; snapshot.hasGpuUtilization = true; @@ -743,7 +743,7 @@ namespace pmon::tel::adl int currentPower = 0; const auto powerResult = pAdl_->Overdrive6_CurrentPower_Get(device.adlAdapterIndex, 0, ¤tPower); - if (pwr::amd::Adl2Wrapper::Ok(powerResult)) { + if (Adl2Wrapper::Ok(powerResult)) { snapshot.gpuPowerW = (double)currentPower / 256.0; snapshot.hasGpuPower = true; } @@ -760,7 +760,7 @@ namespace pmon::tel::adl { ADLODNCapabilitiesX2 capabilities{}; const auto capsResult = pAdl_->OverdriveN_CapabilitiesX2_Get(device.adlAdapterIndex, &capabilities); - if (!pwr::amd::Adl2Wrapper::Ok(capsResult)) { + if (!Adl2Wrapper::Ok(capsResult)) { pmlog_warn("ADL2_OverdriveN_CapabilitiesX2_Get failed").code(capsResult).every(std::chrono::seconds{ 60 }) .pmwatch(device.providerDeviceId) .pmwatch(device.fingerprint.deviceName); @@ -769,7 +769,7 @@ namespace pmon::tel::adl ADLODNPerformanceStatus performanceStatus{}; const auto statusResult = pAdl_->OverdriveN_PerformanceStatus_Get(device.adlAdapterIndex, &performanceStatus); - if (pwr::amd::Adl2Wrapper::Ok(statusResult)) { + if (Adl2Wrapper::Ok(statusResult)) { snapshot.gpuFrequencyMhz = (double)performanceStatus.iCoreClock / 100.0; snapshot.hasGpuFrequency = true; @@ -793,7 +793,7 @@ namespace pmon::tel::adl device.adlAdapterIndex, kOdnGpuTemperatureSensor_, &temperature); - if (pwr::amd::Adl2Wrapper::Ok(tempResult)) { + if (Adl2Wrapper::Ok(tempResult)) { snapshot.gpuTemperatureC = (double)temperature / 1000.0; snapshot.hasGpuTemperature = true; } @@ -805,7 +805,7 @@ namespace pmon::tel::adl ADLODNFanControl fanControl{}; const auto fanResult = pAdl_->OverdriveN_FanControl_Get(device.adlAdapterIndex, &fanControl); - if (pwr::amd::Adl2Wrapper::Ok(fanResult)) { + if (Adl2Wrapper::Ok(fanResult)) { if (HasFlag_(fanControl.iCurrentFanSpeedMode, ADL_OD6_FANSPEED_TYPE_RPM)) { snapshot.fanSpeedsRpm.push_back((double)fanControl.iCurrentFanSpeed); } @@ -824,7 +824,7 @@ namespace pmon::tel::adl int currentPower = 0; const auto powerResult = pAdl_->Overdrive6_CurrentPower_Get(device.adlAdapterIndex, 0, ¤tPower); - if (pwr::amd::Adl2Wrapper::Ok(powerResult)) { + if (Adl2Wrapper::Ok(powerResult)) { snapshot.gpuPowerW = (double)currentPower / 256.0; snapshot.hasGpuPower = true; } @@ -844,7 +844,7 @@ namespace pmon::tel::adl ADLPMLogDataOutput dataOutput{}; dataOutput.size = sizeof(ADLPMLogDataOutput); const auto result = pAdl_->New_QueryPMLogData_Get(device.adlAdapterIndex, &dataOutput); - if (!pwr::amd::Adl2Wrapper::Ok(result)) { + if (!Adl2Wrapper::Ok(result)) { pmlog_warn("ADL2_New_QueryPMLogData_Get failed").code(result).every(std::chrono::seconds{ 60 }) .pmwatch(device.providerDeviceId) .pmwatch(device.fingerprint.deviceName); diff --git a/IntelPresentMon/ControlLib/adl/AmdTelemetryProvider.h b/IntelPresentMon/ControlLib/adl/AmdTelemetryProvider.h index fefb90b5..0aba3578 100644 --- a/IntelPresentMon/ControlLib/adl/AmdTelemetryProvider.h +++ b/IntelPresentMon/ControlLib/adl/AmdTelemetryProvider.h @@ -2,9 +2,9 @@ // SPDX-License-Identifier: MIT #pragma once -#include "../Adl2Wrapper.h" #include "../EndpointCache.h" #include "../TelemetryProvider.h" +#include "Adl2Wrapper.h" #include #include @@ -117,7 +117,7 @@ namespace pmon::tel::adl DynamicSnapshot_& snapshot) const; private: - std::unique_ptr pAdl_{}; + std::unique_ptr pAdl_{}; std::unordered_map devicesById_{}; ProviderDeviceId nextProviderDeviceId_ = 1; }; diff --git a/IntelPresentMon/ControlLib/adl_defines.h b/IntelPresentMon/ControlLib/adl/adl_defines.h similarity index 99% rename from IntelPresentMon/ControlLib/adl_defines.h rename to IntelPresentMon/ControlLib/adl/adl_defines.h index 720732b4..03a81f98 100644 --- a/IntelPresentMon/ControlLib/adl_defines.h +++ b/IntelPresentMon/ControlLib/adl/adl_defines.h @@ -1,4 +1,4 @@ -// +// // Copyright (c) 2016 - 2022 Advanced Micro Devices, Inc. All rights reserved. // // MIT LICENSE: diff --git a/IntelPresentMon/ControlLib/adl_sdk.h b/IntelPresentMon/ControlLib/adl/adl_sdk.h similarity index 99% rename from IntelPresentMon/ControlLib/adl_sdk.h rename to IntelPresentMon/ControlLib/adl/adl_sdk.h index 964e2c01..93dcb423 100644 --- a/IntelPresentMon/ControlLib/adl_sdk.h +++ b/IntelPresentMon/ControlLib/adl/adl_sdk.h @@ -1,4 +1,4 @@ -// +// // Copyright (c) 2016 - 2022 Advanced Micro Devices, Inc. All rights reserved. // // MIT LICENSE: diff --git a/IntelPresentMon/ControlLib/adl_structures.h b/IntelPresentMon/ControlLib/adl/adl_structures.h similarity index 99% rename from IntelPresentMon/ControlLib/adl_structures.h rename to IntelPresentMon/ControlLib/adl/adl_structures.h index 9edb6495..2082e2bb 100644 --- a/IntelPresentMon/ControlLib/adl_structures.h +++ b/IntelPresentMon/ControlLib/adl/adl_structures.h @@ -1,4 +1,4 @@ -// +// // Copyright (c) 2016 - 2022 Advanced Micro Devices, Inc. All rights reserved. // // MIT LICENSE: diff --git a/IntelPresentMon/ControlLib/cApiWrapper_old.cpp b/IntelPresentMon/ControlLib/cApiWrapper_old.cpp deleted file mode 100644 index 8bd953c9..00000000 --- a/IntelPresentMon/ControlLib/cApiWrapper_old.cpp +++ /dev/null @@ -1,5784 +0,0 @@ -//=========================================================================== -//Copyright (C) 2025 Intel Corporation -// -// -// -//SPDX-License-Identifier: MIT -//-------------------------------------------------------------------------- - -/** - * - * @file ctl_api.cpp - * @version v1-r1 - * - */ - -// Note: UWP applications should have defined WINDOWS_UWP in their compiler settings -// Also at this point, it's easier by not enabling pre-compiled option to compile this file -// Not all functionalities are tested for a UWP application - -#include -#include -#include - -//#define CTL_APIEXPORT - -#include "igcl_api.h" - -///////////////////////////////////////////////////////////////////////////////// -// -// Implementation of wrapper functions -// -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 - #define CTL_DLL_NAME L"ControlLib32" -#endif -#define CTL_DLL_PATH_LEN 512 - -ctl_result_t GetControlAPIDLLPath(ctl_init_args_t* pInitArgs, wchar_t* pwcDLLPath) -{ - if ((NULL == pRuntimeArgs) || (NULL == pRuntimeArgs->pRuntimePath)) - { - // Load the requested DLL based on major version in init args - uint16_t majorVersion = CTL_MAJOR_VERSION(pInitArgs->AppVersion); - - // If caller's major version is higher than the DLL's, then simply not support the caller! - // This is not supposed to happen as wrapper is part of the app itself which includes igcl_api.h with right major version - 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) - { - // caller specified a specific RT, use it instead - wcsncpy_s(pwcDLLPath, CTL_DLL_PATH_LEN, pRuntimeArgs->pRuntimePath, CTL_DLL_PATH_LEN - 1); - } - return CTL_RESULT_SUCCESS; -} - - - -/** -* @brief Control Api Init -* -* @details -* - Control Api Init -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pInitDesc` -* + `nullptr == phAPIHandle` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlInit( - ctl_init_args_t* pInitDesc, ///< [in][out] App's control API version - ctl_api_handle_t* phAPIHandle ///< [in][out][release] Control API handle - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - // special code - only for ctlInit() - if (NULL == hinstLib) - { - 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.data(), 0); -#else - DWORD dwFlags = LOAD_LIBRARY_SEARCH_SYSTEM32; -#ifdef _DEBUG - dwFlags = dwFlags | LOAD_LIBRARY_SEARCH_APPLICATION_DIR; -#endif - hinstLib = LoadLibraryExW(strDLLPath.data(), NULL, dwFlags); -#endif - if (NULL == hinstLib) - { - result = CTL_RESULT_ERROR_LOAD; - } - else if (pRuntimeArgs) - { - ctlSetRuntimePath(pRuntimeArgs); - } - } - } - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnInit_t pfnInit = (ctl_pfnInit_t)GetProcAddress(hinstLibPtr, "ctlInit"); - if (pfnInit) - { - result = pfnInit(pInitDesc, phAPIHandle); - } - } - - return result; -} - - -/** -* @brief Control Api Destroy -* -* @details -* - Control Api Close -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hAPIHandle` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlClose( - ctl_api_handle_t hAPIHandle ///< [in][release] Control API implementation handle obtained during init - ///< call - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnClose_t pfnClose = (ctl_pfnClose_t)GetProcAddress(hinstLibPtr, "ctlClose"); - if (pfnClose) - { - result = pfnClose(hAPIHandle); - } - } - - // 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 - if( result == CTL_RESULT_SUCCESS) - { - if (NULL != hinstLib) - { - FreeLibrary(hinstLib); - hinstLib = NULL; - } - } - // set runtime args back to NULL - // no need to free this as it's allocated by caller - pRuntimeArgs = NULL; - return result; -} - - -/** -* @brief Runtime path -* -* @details -* - Control Api set runtime path. Optional call from a loader which allows -* the loaded runtime to enumerate only the adapters which the specified -* runtime is responsible for. This is done usually by a loader or by -* callers who know how to get the specific runtime of interest. This -* call right now is reserved for use by Intel components. -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pArgs` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlSetRuntimePath( - ctl_runtime_path_args_t* pArgs ///< [in] Runtime path - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnSetRuntimePath_t pfnSetRuntimePath = (ctl_pfnSetRuntimePath_t)GetProcAddress(hinstLibPtr, "ctlSetRuntimePath"); - if (pfnSetRuntimePath) - { - result = pfnSetRuntimePath(pArgs); - } - } - - // 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 - 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 - pRuntimeArgs = pArgs; - result = CTL_RESULT_SUCCESS; - } - return result; -} - - -/** -* @brief Wait for a property change. Note that this is a blocking call -* -* @details -* - Wait for a property change in display, 3d, media etc. -* -* @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 == pArgs` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlWaitForPropertyChange( - ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter - ctl_wait_property_change_args_t* pArgs ///< [in] Argument containing information about which property changes to - ///< listen for - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnWaitForPropertyChange_t pfnWaitForPropertyChange = (ctl_pfnWaitForPropertyChange_t)GetProcAddress(hinstLibPtr, "ctlWaitForPropertyChange"); - if (pfnWaitForPropertyChange) - { - result = pfnWaitForPropertyChange(hDeviceAdapter, pArgs); - } - } - - return result; -} - - -/** -* @brief Reserved function -* -* @details -* - Reserved function -* -* @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 == pArgs` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlReservedCall( - ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter - ctl_reserved_args_t* pArgs ///< [in] Argument containing information - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnReservedCall_t pfnReservedCall = (ctl_pfnReservedCall_t)GetProcAddress(hinstLibPtr, "ctlReservedCall"); - if (pfnReservedCall) - { - result = pfnReservedCall(hDeviceAdapter, pArgs); - } - } - - return result; -} - - -/** -* @brief Get 3D capabilities -* -* @details -* - The application gets 3D 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 -ctlGetSupported3DCapabilities( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter - ctl_3d_feature_caps_t* pFeatureCaps ///< [in,out][release] 3D properties - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetSupported3DCapabilities_t pfnGetSupported3DCapabilities = (ctl_pfnGetSupported3DCapabilities_t)GetProcAddress(hinstLibPtr, "ctlGetSupported3DCapabilities"); - if (pfnGetSupported3DCapabilities) - { - result = pfnGetSupported3DCapabilities(hDAhandle, pFeatureCaps); - } - } - - return result; -} - - -/** -* @brief Get/Set 3D feature -* -* @details -* - 3D 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 -ctlGetSet3DFeature( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter - ctl_3d_feature_getset_t* pFeature ///< [in][release] 3D feature get/set parameter - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetSet3DFeature_t pfnGetSet3DFeature = (ctl_pfnGetSet3DFeature_t)GetProcAddress(hinstLibPtr, "ctlGetSet3DFeature"); - if (pfnGetSet3DFeature) - { - result = pfnGetSet3DFeature(hDAhandle, pFeature); - } - } - - return result; -} - - -/** -* @brief Check Driver version -* -* @details -* - The application checks driver version -* -* @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_t CTL_APICALL -ctlCheckDriverVersion( - ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter - ctl_version_info_t version_info ///< [in][release] Driver version info - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnCheckDriverVersion_t pfnCheckDriverVersion = (ctl_pfnCheckDriverVersion_t)GetProcAddress(hinstLibPtr, "ctlCheckDriverVersion"); - if (pfnCheckDriverVersion) - { - result = pfnCheckDriverVersion(hDeviceAdapter, version_info); - } - } - - return result; -} - - -/** -* @brief Enumerate devices -* -* @details -* - The application enumerates all device adapters 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` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlEnumerateDevices( - 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 device instances. If count - ///< is zero, then the api will update the value with the total - ///< number of drivers available. If count is non-zero, then the api will - ///< only retrieve the number of drivers. - ///< If count is larger than the number of drivers available, then the api - ///< will update the value with the correct number of drivers available. - ctl_device_adapter_handle_t* phDevices ///< [in,out][optional][release][range(0, *pCount)] array of driver - ///< instance handles - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnEnumerateDevices_t pfnEnumerateDevices = (ctl_pfnEnumerateDevices_t)GetProcAddress(hinstLibPtr, "ctlEnumerateDevices"); - if (pfnEnumerateDevices) - { - result = pfnEnumerateDevices(hAPIHandle, pCount, phDevices); - } - } - - return result; -} - - -/** -* @brief Enumerate display outputs -* -* @details -* - Enumerates display output capabilities -* -* @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_t CTL_APICALL -ctlEnumerateDisplayOutputs( - ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter - uint32_t* pCount, ///< [in,out][release] pointer to the number of display output instances. - ///< 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 drivers available, then the api - ///< will update the value with the correct number of drivers available. - ctl_display_output_handle_t* phDisplayOutputs ///< [in,out][optional][release][range(0, *pCount)] array of display output - ///< instance handles - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnEnumerateDisplayOutputs_t pfnEnumerateDisplayOutputs = (ctl_pfnEnumerateDisplayOutputs_t)GetProcAddress(hinstLibPtr, "ctlEnumerateDisplayOutputs"); - if (pfnEnumerateDisplayOutputs) - { - result = pfnEnumerateDisplayOutputs(hDeviceAdapter, pCount, phDisplayOutputs); - } - } - - return result; -} - - -/** -* @brief Enumerate I2C Pin Pairs -* -* @details -* - Returns available list of I2C Pin-Pairs on a requested adapter -* -* @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_POINTER - "The incoming pointer pCount is null" -* - ::CTL_RESULT_ERROR_INVALID_SIZE - "The supplied Count is not equal to actual number of i2c pin-pair instances" -*/ -ctl_result_t CTL_APICALL -ctlEnumerateI2CPinPairs( - ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to device adapter - uint32_t* pCount, ///< [in,out][release] pointer to the number of i2c pin-pair instances. If - ///< count is zero, then the api will update the value with the total - ///< number of i2c pin-pair instances available. If count is non-zero and - ///< matches the avaialble number of pin-pairs, then the api will only - ///< return the avaialble number of i2c pin-pair instances in phI2cPinPairs. - ctl_i2c_pin_pair_handle_t* phI2cPinPairs ///< [out][optional][release][range(0, *pCount)] array of i2c pin pair - ///< instance handles. Need to be allocated by Caller when supplying the - ///< *pCount > 0. - ///< If Count is not equal to actual number of i2c pin-pair instances, it - ///< will return CTL_RESULT_ERROR_INVALID_SIZE. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnEnumerateI2CPinPairs_t pfnEnumerateI2CPinPairs = (ctl_pfnEnumerateI2CPinPairs_t)GetProcAddress(hinstLibPtr, "ctlEnumerateI2CPinPairs"); - if (pfnEnumerateI2CPinPairs) - { - result = pfnEnumerateI2CPinPairs(hDeviceAdapter, pCount, phI2cPinPairs); - } - } - - return result; -} - - -/** -* @brief Get Device Properties -* -* @details -* - The application gets device 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 == pProperties` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlGetDeviceProperties( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to control device adapter - ctl_device_adapter_properties_t* pProperties ///< [in,out][release] Query result for device properties - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetDeviceProperties_t pfnGetDeviceProperties = (ctl_pfnGetDeviceProperties_t)GetProcAddress(hinstLibPtr, "ctlGetDeviceProperties"); - if (pfnGetDeviceProperties) - { - result = pfnGetDeviceProperties(hDAhandle, pProperties); - } - } - - return result; -} - - -/** -* @brief Get Display Properties -* -* @details -* - The application gets display properties -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pProperties` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlGetDisplayProperties( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_display_properties_t* pProperties ///< [in,out][release] Query result for display properties - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetDisplayProperties_t pfnGetDisplayProperties = (ctl_pfnGetDisplayProperties_t)GetProcAddress(hinstLibPtr, "ctlGetDisplayProperties"); - if (pfnGetDisplayProperties) - { - result = pfnGetDisplayProperties(hDisplayOutput, pProperties); - } - } - - return result; -} - - -/** -* @brief Get Adapter Display encoder Properties -* -* @details -* - The application gets the graphic adapters display encoder properties -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pProperties` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlGetAdaperDisplayEncoderProperties( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_adapter_display_encoder_properties_t* pProperties ///< [in,out][release] Query result for adapter display encoder properties - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetAdaperDisplayEncoderProperties_t pfnGetAdaperDisplayEncoderProperties = (ctl_pfnGetAdaperDisplayEncoderProperties_t)GetProcAddress(hinstLibPtr, "ctlGetAdaperDisplayEncoderProperties"); - if (pfnGetAdaperDisplayEncoderProperties) - { - result = pfnGetAdaperDisplayEncoderProperties(hDisplayOutput, pProperties); - } - } - - return result; -} - - -/** -* @brief Get Level0 Device handle -* -* @details -* - The application gets OneAPI Level0 Device handles -* -* @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 == pZeDevice` -* + `nullptr == hInstance` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlGetZeDevice( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter - void* pZeDevice, ///< [out][release] ze_device handle - void** hInstance ///< [out][release] Module instance which caller can use to get export - ///< functions directly - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetZeDevice_t pfnGetZeDevice = (ctl_pfnGetZeDevice_t)GetProcAddress(hinstLibPtr, "ctlGetZeDevice"); - if (pfnGetZeDevice) - { - result = pfnGetZeDevice(hDAhandle, pZeDevice, hInstance); - } - } - - return result; -} - - -/** -* @brief Get Sharpness capability -* -* @details -* - Returns sharpness capability -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pSharpnessCaps` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlGetSharpnessCaps( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_sharpness_caps_t* pSharpnessCaps ///< [in,out][release] Query result for sharpness capability - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetSharpnessCaps_t pfnGetSharpnessCaps = (ctl_pfnGetSharpnessCaps_t)GetProcAddress(hinstLibPtr, "ctlGetSharpnessCaps"); - if (pfnGetSharpnessCaps) - { - result = pfnGetSharpnessCaps(hDisplayOutput, pSharpnessCaps); - } - } - - return result; -} - - -/** -* @brief Get Sharpness setting -* -* @details -* - Returns current sharpness settings -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pSharpnessSettings` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlGetCurrentSharpness( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_sharpness_settings_t* pSharpnessSettings ///< [in,out][release] Query result for sharpness current settings - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetCurrentSharpness_t pfnGetCurrentSharpness = (ctl_pfnGetCurrentSharpness_t)GetProcAddress(hinstLibPtr, "ctlGetCurrentSharpness"); - if (pfnGetCurrentSharpness) - { - result = pfnGetCurrentSharpness(hDisplayOutput, pSharpnessSettings); - } - } - - return result; -} - - -/** -* @brief Set Sharpness setting -* -* @details -* - Set current sharpness settings -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pSharpnessSettings` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlSetCurrentSharpness( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_sharpness_settings_t* pSharpnessSettings ///< [in][release] Set sharpness current settings - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnSetCurrentSharpness_t pfnSetCurrentSharpness = (ctl_pfnSetCurrentSharpness_t)GetProcAddress(hinstLibPtr, "ctlSetCurrentSharpness"); - if (pfnSetCurrentSharpness) - { - result = pfnSetCurrentSharpness(hDisplayOutput, pSharpnessSettings); - } - } - - return result; -} - - -/** -* @brief I2C Access -* -* @details -* - Interface to access I2C using display handle as identifier. I2C -* driver override flags are supported only for HDMI displays. -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pI2cAccessArgs` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" -* - ::CTL_RESULT_ERROR_INVALID_SIZE - "Invalid I2C data size" -* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" -* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -* - ::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 - "Kernal mode driver call failure" -*/ -ctl_result_t CTL_APICALL -ctlI2CAccess( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_i2c_access_args_t* pI2cAccessArgs ///< [in,out] I2c access arguments - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnI2CAccess_t pfnI2CAccess = (ctl_pfnI2CAccess_t)GetProcAddress(hinstLibPtr, "ctlI2CAccess"); - if (pfnI2CAccess) - { - result = pfnI2CAccess(hDisplayOutput, pI2cAccessArgs); - } - } - - return result; -} - - -/** -* @brief I2C Access On Pin Pair -* -* @details -* - Interface to access I2C using pin-pair handle as identifier. -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hI2cPinPair` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pI2cAccessArgs` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" -* - ::CTL_RESULT_ERROR_INVALID_SIZE - "Invalid I2C data size" -* - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid Args passed" -* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" -* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -* - ::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 - "Kernal mode driver call failure" -* - ::CTL_RESULT_ERROR_INVALID_NULL_HANDLE - "Invalid or Null handle passed" -* - ::CTL_RESULT_ERROR_EXTERNAL_DISPLAY_ATTACHED - "Write to Address not allowed when Display is connected" -*/ -ctl_result_t CTL_APICALL -ctlI2CAccessOnPinPair( - ctl_i2c_pin_pair_handle_t hI2cPinPair, ///< [in] Handle to I2C pin pair. - ctl_i2c_access_pinpair_args_t* pI2cAccessArgs ///< [in,out] I2c access arguments. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnI2CAccessOnPinPair_t pfnI2CAccessOnPinPair = (ctl_pfnI2CAccessOnPinPair_t)GetProcAddress(hinstLibPtr, "ctlI2CAccessOnPinPair"); - if (pfnI2CAccessOnPinPair) - { - result = pfnI2CAccessOnPinPair(hI2cPinPair, pI2cAccessArgs); - } - } - - return result; -} - - -/** -* @brief Aux Access -* -* @details -* - The application does Aux access, PSR needs to be disabled for AUX -* call. -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pAuxAccessArgs` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" -* - ::CTL_RESULT_ERROR_INVALID_SIZE - "Invalid AUX data size" -* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" -* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -* - ::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_INVALID_AUX_ACCESS_FLAG - "Invalid flag for AUX access" -* - ::CTL_RESULT_ERROR_KMD_CALL - "Kernal mode driver call failure" -*/ -ctl_result_t CTL_APICALL -ctlAUXAccess( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_aux_access_args_t* pAuxAccessArgs ///< [in,out] Aux access arguments - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnAUXAccess_t pfnAUXAccess = (ctl_pfnAUXAccess_t)GetProcAddress(hinstLibPtr, "ctlAUXAccess"); - if (pfnAUXAccess) - { - result = pfnAUXAccess(hDisplayOutput, pAuxAccessArgs); - } - } - - return result; -} - - -/** -* @brief Get Power optimization features -* -* @details -* - Returns power optimization capabilities -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pPowerOptimizationCaps` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlGetPowerOptimizationCaps( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_power_optimization_caps_t* pPowerOptimizationCaps ///< [in,out][release] Query result for power optimization features - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetPowerOptimizationCaps_t pfnGetPowerOptimizationCaps = (ctl_pfnGetPowerOptimizationCaps_t)GetProcAddress(hinstLibPtr, "ctlGetPowerOptimizationCaps"); - if (pfnGetPowerOptimizationCaps) - { - result = pfnGetPowerOptimizationCaps(hDisplayOutput, pPowerOptimizationCaps); - } - } - - return result; -} - - -/** -* @brief Get Power optimization setting -* -* @details -* - Returns power optimization setting for a specific feature -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pPowerOptimizationSettings` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_INVALID_POWERFEATURE_OPTIMIZATION_FLAG - "Unsupported PowerOptimizationFeature" -* - ::CTL_RESULT_ERROR_INVALID_POWERSOURCE_TYPE_FOR_DPST - "DPST is supported only in DC Mode" -*/ -ctl_result_t CTL_APICALL -ctlGetPowerOptimizationSetting( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_power_optimization_settings_t* pPowerOptimizationSettings ///< [in,out][release] Power optimization data to be fetched - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetPowerOptimizationSetting_t pfnGetPowerOptimizationSetting = (ctl_pfnGetPowerOptimizationSetting_t)GetProcAddress(hinstLibPtr, "ctlGetPowerOptimizationSetting"); - if (pfnGetPowerOptimizationSetting) - { - result = pfnGetPowerOptimizationSetting(hDisplayOutput, pPowerOptimizationSettings); - } - } - - return result; -} - - -/** -* @brief Set Power optimization setting -* -* @details -* - Set power optimization setting for a specific feature -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pPowerOptimizationSettings` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_INVALID_POWERFEATURE_OPTIMIZATION_FLAG - "Unsupported PowerOptimizationFeature" -* - ::CTL_RESULT_ERROR_INVALID_POWERSOURCE_TYPE_FOR_DPST - "DPST is supported only in DC Mode" -* - ::CTL_RESULT_ERROR_SET_FBC_FEATURE_NOT_SUPPORTED - "Set FBC Feature not supported" -*/ -ctl_result_t CTL_APICALL -ctlSetPowerOptimizationSetting( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_power_optimization_settings_t* pPowerOptimizationSettings ///< [in][release] Power optimization data to be applied - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnSetPowerOptimizationSetting_t pfnSetPowerOptimizationSetting = (ctl_pfnSetPowerOptimizationSetting_t)GetProcAddress(hinstLibPtr, "ctlSetPowerOptimizationSetting"); - if (pfnSetPowerOptimizationSetting) - { - result = pfnSetPowerOptimizationSetting(hDisplayOutput, pPowerOptimizationSettings); - } - } - - return result; -} - - -/** -* @brief Set Brightness on companion display -* -* @details -* - Set Brightness for a target display. Currently support is only for -* companion display. -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pSetBrightnessSetting` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid Brightness data passed as argument" -* - ::CTL_RESULT_ERROR_DISPLAY_NOT_ACTIVE - "Display not active" -* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Currently Brightness API is supported only on companion display" -*/ -ctl_result_t CTL_APICALL -ctlSetBrightnessSetting( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_set_brightness_t* pSetBrightnessSetting ///< [in][release] Brightness settings to be applied - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnSetBrightnessSetting_t pfnSetBrightnessSetting = (ctl_pfnSetBrightnessSetting_t)GetProcAddress(hinstLibPtr, "ctlSetBrightnessSetting"); - if (pfnSetBrightnessSetting) - { - result = pfnSetBrightnessSetting(hDisplayOutput, pSetBrightnessSetting); - } - } - - return result; -} - - -/** -* @brief Get Brightness setting -* -* @details -* - Get Brightness for a target display. Currently support is only for -* companion display. -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pGetBrightnessSetting` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_DISPLAY_NOT_ACTIVE - "Display not active" -* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Currently Brightness API is supported only on companion display" -*/ -ctl_result_t CTL_APICALL -ctlGetBrightnessSetting( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_get_brightness_t* pGetBrightnessSetting ///< [out][release] Brightness settings data to be fetched - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetBrightnessSetting_t pfnGetBrightnessSetting = (ctl_pfnGetBrightnessSetting_t)GetProcAddress(hinstLibPtr, "ctlGetBrightnessSetting"); - if (pfnGetBrightnessSetting) - { - result = pfnGetBrightnessSetting(hDisplayOutput, pGetBrightnessSetting); - } - } - - return result; -} - - -/** -* @brief Pixel transformation get pipe configuration -* -* @details -* - The application does pixel transformation get pipe configuration -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pPixTxGetConfigArgs` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" -* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -* - ::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 - "Kernal mode driver call failure" -* - ::CTL_RESULT_ERROR_INVALID_PIXTX_GET_CONFIG_QUERY_TYPE - "Invalid query type" -* - ::CTL_RESULT_ERROR_INVALID_PIXTX_BLOCK_ID - "Invalid block id" -* - ::CTL_RESULT_ERROR_INSUFFICIENT_PIXTX_BLOCK_CONFIG_MEMORY - "Insufficient memery allocated for BlockConfigs" -* - ::CTL_RESULT_ERROR_3DLUT_INVALID_PIPE - "Invalid pipe for 3dlut" -* - ::CTL_RESULT_ERROR_3DLUT_INVALID_DATA - "Invalid 3dlut data" -* - ::CTL_RESULT_ERROR_3DLUT_NOT_SUPPORTED_IN_HDR - "3dlut not supported in HDR" -* - ::CTL_RESULT_ERROR_3DLUT_INVALID_OPERATION - "Invalid 3dlut operation" -* - ::CTL_RESULT_ERROR_3DLUT_UNSUCCESSFUL - "3dlut call unsuccessful" -*/ -ctl_result_t CTL_APICALL -ctlPixelTransformationGetConfig( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_pixtx_pipe_get_config_t* pPixTxGetConfigArgs///< [in,out] Pixel transformation get pipe configiguration arguments - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnPixelTransformationGetConfig_t pfnPixelTransformationGetConfig = (ctl_pfnPixelTransformationGetConfig_t)GetProcAddress(hinstLibPtr, "ctlPixelTransformationGetConfig"); - if (pfnPixelTransformationGetConfig) - { - result = pfnPixelTransformationGetConfig(hDisplayOutput, pPixTxGetConfigArgs); - } - } - - return result; -} - - -/** -* @brief Pixel transformation set pipe configuration -* -* @details -* - The application does pixel transformation set pipe configuration -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pPixTxSetConfigArgs` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" -* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -* - ::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 - "Kernal mode driver call failure" -* - ::CTL_RESULT_ERROR_INVALID_PIXTX_SET_CONFIG_OPERATION_TYPE - "Invalid operation type" -* - ::CTL_RESULT_ERROR_INVALID_SET_CONFIG_NUMBER_OF_SAMPLES - "Invalid number of samples" -* - ::CTL_RESULT_ERROR_INVALID_PIXTX_BLOCK_ID - "Invalid block id" -* - ::CTL_RESULT_ERROR_PERSISTANCE_NOT_SUPPORTED - "Persistance not supported" -* - ::CTL_RESULT_ERROR_3DLUT_INVALID_PIPE - "Invalid pipe for 3dlut" -* - ::CTL_RESULT_ERROR_3DLUT_INVALID_DATA - "Invalid 3dlut data" -* - ::CTL_RESULT_ERROR_3DLUT_NOT_SUPPORTED_IN_HDR - "3dlut not supported in HDR" -* - ::CTL_RESULT_ERROR_3DLUT_INVALID_OPERATION - "Invalid 3dlut operation" -* - ::CTL_RESULT_ERROR_3DLUT_UNSUCCESSFUL - "3dlut call unsuccessful" -*/ -ctl_result_t CTL_APICALL -ctlPixelTransformationSetConfig( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_pixtx_pipe_set_config_t* pPixTxSetConfigArgs///< [in,out] Pixel transformation set pipe configiguration arguments - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnPixelTransformationSetConfig_t pfnPixelTransformationSetConfig = (ctl_pfnPixelTransformationSetConfig_t)GetProcAddress(hinstLibPtr, "ctlPixelTransformationSetConfig"); - if (pfnPixelTransformationSetConfig) - { - result = pfnPixelTransformationSetConfig(hDisplayOutput, pPixTxSetConfigArgs); - } - } - - return result; -} - - -/** -* @brief Panel Descriptor Access -* -* @details -* - The application does EDID or Display ID access -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pPanelDescriptorAccessArgs` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" -* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" -* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -* - ::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 - "Kernal mode driver call failure" -*/ -ctl_result_t CTL_APICALL -ctlPanelDescriptorAccess( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_panel_descriptor_access_args_t* pPanelDescriptorAccessArgs ///< [in,out] Panel descriptor access arguments - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnPanelDescriptorAccess_t pfnPanelDescriptorAccess = (ctl_pfnPanelDescriptorAccess_t)GetProcAddress(hinstLibPtr, "ctlPanelDescriptorAccess"); - if (pfnPanelDescriptorAccess) - { - result = pfnPanelDescriptorAccess(hDisplayOutput, pPanelDescriptorAccessArgs); - } - } - - return result; -} - - -/** -* @brief Get Supported Retro Scaling Types -* -* @details -* - Returns supported retro scaling capabilities -* -* @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 == pRetroScalingCaps` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlGetSupportedRetroScalingCapability( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to adapter - ctl_retro_scaling_caps_t* pRetroScalingCaps ///< [in,out][release] Query result for supported retro scaling types - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetSupportedRetroScalingCapability_t pfnGetSupportedRetroScalingCapability = (ctl_pfnGetSupportedRetroScalingCapability_t)GetProcAddress(hinstLibPtr, "ctlGetSupportedRetroScalingCapability"); - if (pfnGetSupportedRetroScalingCapability) - { - result = pfnGetSupportedRetroScalingCapability(hDAhandle, pRetroScalingCaps); - } - } - - return result; -} - - -/** -* @brief Get/Set Retro Scaling -* -* @details -* - Get or Set the status of retro scaling.This Api will do a physical -* modeset resulting in flash on the screen -* -* @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 == pGetSetRetroScalingType` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlGetSetRetroScaling( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to adapter - ctl_retro_scaling_settings_t* pGetSetRetroScalingType ///< [in,out][release] Get or Set the retro scaling type - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetSetRetroScaling_t pfnGetSetRetroScaling = (ctl_pfnGetSetRetroScaling_t)GetProcAddress(hinstLibPtr, "ctlGetSetRetroScaling"); - if (pfnGetSetRetroScaling) - { - result = pfnGetSetRetroScaling(hDAhandle, pGetSetRetroScalingType); - } - } - - return result; -} - - -/** -* @brief Get Supported Scaling Types -* -* @details -* - Returns supported scaling capabilities -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pScalingCaps` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlGetSupportedScalingCapability( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_scaling_caps_t* pScalingCaps ///< [in,out][release] Query result for supported scaling types - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetSupportedScalingCapability_t pfnGetSupportedScalingCapability = (ctl_pfnGetSupportedScalingCapability_t)GetProcAddress(hinstLibPtr, "ctlGetSupportedScalingCapability"); - if (pfnGetSupportedScalingCapability) - { - result = pfnGetSupportedScalingCapability(hDisplayOutput, pScalingCaps); - } - } - - return result; -} - - -/** -* @brief Get Current Scaling -* -* @details -* - Returns current active scaling -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pGetCurrentScalingType` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlGetCurrentScaling( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_scaling_settings_t* pGetCurrentScalingType ///< [in,out][release] Query result for active scaling types - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetCurrentScaling_t pfnGetCurrentScaling = (ctl_pfnGetCurrentScaling_t)GetProcAddress(hinstLibPtr, "ctlGetCurrentScaling"); - if (pfnGetCurrentScaling) - { - result = pfnGetCurrentScaling(hDisplayOutput, pGetCurrentScalingType); - } - } - - return result; -} - - -/** -* @brief Set Scaling Type -* -* @details -* - Returns current active scaling -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pSetScalingType` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlSetCurrentScaling( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_scaling_settings_t* pSetScalingType ///< [in,out][release] Set scaling types - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnSetCurrentScaling_t pfnSetCurrentScaling = (ctl_pfnSetCurrentScaling_t)GetProcAddress(hinstLibPtr, "ctlSetCurrentScaling"); - if (pfnSetCurrentScaling) - { - result = pfnSetCurrentScaling(hDisplayOutput, pSetScalingType); - } - } - - return result; -} - - -/** -* @brief Get LACE Config -* -* @details -* - Returns current LACE Config -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pLaceConfig` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_LACE_INVALID_DATA_ARGUMENT_PASSED - "Lace Incorrrect AggressivePercent data or LuxVsAggressive Map data passed by user" -*/ -ctl_result_t CTL_APICALL -ctlGetLACEConfig( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_lace_config_t* pLaceConfig ///< [out]Lace configuration - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetLACEConfig_t pfnGetLACEConfig = (ctl_pfnGetLACEConfig_t)GetProcAddress(hinstLibPtr, "ctlGetLACEConfig"); - if (pfnGetLACEConfig) - { - result = pfnGetLACEConfig(hDisplayOutput, pLaceConfig); - } - } - - return result; -} - - -/** -* @brief Sets LACE Config -* -* @details -* - Sets LACE Config -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pLaceConfig` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_LACE_INVALID_DATA_ARGUMENT_PASSED - "Lace Incorrrect AggressivePercent data or LuxVsAggressive Map data passed by user" -*/ -ctl_result_t CTL_APICALL -ctlSetLACEConfig( - ctl_display_output_handle_t hDisplayOutput, ///< [in]Handle to display output - ctl_lace_config_t* pLaceConfig ///< [in]Lace configuration - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnSetLACEConfig_t pfnSetLACEConfig = (ctl_pfnSetLACEConfig_t)GetProcAddress(hinstLibPtr, "ctlSetLACEConfig"); - if (pfnSetLACEConfig) - { - result = pfnSetLACEConfig(hDisplayOutput, pLaceConfig); - } - } - - return result; -} - - -/** -* @brief Get Software PSR caps/Set software PSR State -* -* @details -* - Returns Software PSR status or Sets Software PSR capabilities. This is -* a reserved capability. By default, software PSR is not supported/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 == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pSoftwarePsrSetting` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlSoftwarePSR( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_sw_psr_settings_t* pSoftwarePsrSetting ///< [in,out][release] Get Software PSR caps/state or Set Software PSR - ///< state - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnSoftwarePSR_t pfnSoftwarePSR = (ctl_pfnSoftwarePSR_t)GetProcAddress(hinstLibPtr, "ctlSoftwarePSR"); - if (pfnSoftwarePSR) - { - result = pfnSoftwarePSR(hDisplayOutput, pSoftwarePsrSetting); - } - } - - return result; -} - - -/** -* @brief Get Intel Arc Sync information for monitor -* -* @details -* - Returns Intel Arc Sync information for selected monitor -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pIntelArcSyncMonitorParams` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlGetIntelArcSyncInfoForMonitor( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_intel_arc_sync_monitor_params_t* pIntelArcSyncMonitorParams ///< [in,out][release] Intel Arc Sync params for monitor - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetIntelArcSyncInfoForMonitor_t pfnGetIntelArcSyncInfoForMonitor = (ctl_pfnGetIntelArcSyncInfoForMonitor_t)GetProcAddress(hinstLibPtr, "ctlGetIntelArcSyncInfoForMonitor"); - if (pfnGetIntelArcSyncInfoForMonitor) - { - result = pfnGetIntelArcSyncInfoForMonitor(hDisplayOutput, pIntelArcSyncMonitorParams); - } - } - - return result; -} - - -/** -* @brief Get Intel Arc Sync profile -* -* @details -* - Returns Intel Arc Sync profile for selected monitor -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pIntelArcSyncProfileParams` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlGetIntelArcSyncProfile( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_intel_arc_sync_profile_params_t* pIntelArcSyncProfileParams ///< [in,out][release] Intel Arc Sync params for monitor - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetIntelArcSyncProfile_t pfnGetIntelArcSyncProfile = (ctl_pfnGetIntelArcSyncProfile_t)GetProcAddress(hinstLibPtr, "ctlGetIntelArcSyncProfile"); - if (pfnGetIntelArcSyncProfile) - { - result = pfnGetIntelArcSyncProfile(hDisplayOutput, pIntelArcSyncProfileParams); - } - } - - return result; -} - - -/** -* @brief Set Intel Arc Sync profile -* -* @details -* - Sets Intel Arc Sync profile for selected monitor. In a mux situation, -* this API should be called for all display IDs associated with a -* physical display. -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pIntelArcSyncProfileParams` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -*/ -ctl_result_t CTL_APICALL -ctlSetIntelArcSyncProfile( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_intel_arc_sync_profile_params_t* pIntelArcSyncProfileParams ///< [in][release] Intel Arc Sync params for monitor - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnSetIntelArcSyncProfile_t pfnSetIntelArcSyncProfile = (ctl_pfnSetIntelArcSyncProfile_t)GetProcAddress(hinstLibPtr, "ctlSetIntelArcSyncProfile"); - if (pfnSetIntelArcSyncProfile) - { - result = pfnSetIntelArcSyncProfile(hDisplayOutput, pIntelArcSyncProfileParams); - } - } - - return result; -} - - -/** -* @brief EDID Management allows managing an output's EDID or Plugged Status. -* -* @details -* - To manage output's EDID or Display ID. Supports native DP SST and HDMI -* Display types. -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pEdidManagementArgs` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" -* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -* - ::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 - "Kernal mode driver call failure" -* - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid combination of parameters" -* - ::CTL_RESULT_ERROR_DISPLAY_NOT_ATTACHED - "Error for Output Device not attached" -* - ::CTL_RESULT_ERROR_OUT_OF_DEVICE_MEMORY - "Insufficient device memory to satisfy call" -* - ::CTL_RESULT_ERROR_DATA_NOT_FOUND - "Requested EDID data not present." -*/ -ctl_result_t CTL_APICALL -ctlEdidManagement( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_edid_management_args_t* pEdidManagementArgs ///< [in,out] EDID management arguments - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnEdidManagement_t pfnEdidManagement = (ctl_pfnEdidManagement_t)GetProcAddress(hinstLibPtr, "ctlEdidManagement"); - if (pfnEdidManagement) - { - result = pfnEdidManagement(hDisplayOutput, pEdidManagementArgs); - } - } - - return result; -} - - -/** -* @brief Get/Set Custom mode. -* -* @details -* - To get or set custom mode. -* - Add custom source mode operation supports only single mode additon at -* a time. -* - Remove custom source mode operation supports single or multiple mode -* removal at a time. -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pCustomModeArgs` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" -* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -* - ::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 - "Kernal mode driver call failure" -* - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid combination of parameters" -* - ::CTL_RESULT_ERROR_CUSTOM_MODE_STANDARD_CUSTOM_MODE_EXISTS - "Standard custom mode exists" -* - ::CTL_RESULT_ERROR_CUSTOM_MODE_NON_CUSTOM_MATCHING_MODE_EXISTS - "Non custom matching mode exists" -* - ::CTL_RESULT_ERROR_CUSTOM_MODE_INSUFFICIENT_MEMORY - "Custom mode insufficent memory" -*/ -ctl_result_t CTL_APICALL -ctlGetSetCustomMode( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_get_set_custom_mode_args_t* pCustomModeArgs ///< [in,out] Custom mode arguments - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetSetCustomMode_t pfnGetSetCustomMode = (ctl_pfnGetSetCustomMode_t)GetProcAddress(hinstLibPtr, "ctlGetSetCustomMode"); - if (pfnGetSetCustomMode) - { - result = pfnGetSetCustomMode(hDisplayOutput, pCustomModeArgs); - } - } - - return result; -} - - -/** -* @brief Get/Set Combined Display -* -* @details -* - To get or set combined display with given Child Targets on a Single -* GPU or across identical GPUs. Multi-GPU(MGPU) combined display is -* reserved i.e. it is not public and requires special application GUID. -* MGPU Combined Display will get activated or deactivated in next boot. -* MGPU scenario will internally link the associated adapters via Linked -* Display Adapter Call, with supplied hDeviceAdapter being the LDA -* Primary. If Genlock and enabled in Driver registry and supported by -* given Display Config, MGPU Combined Display will enable MGPU Genlock -* with supplied hDeviceAdapter being the Genlock Primary Adapter and the -* First Child Display being the Primary Display. -* -* @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 == pCombinedDisplayArgs` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" -* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" -* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -* - ::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_FEATURE_NOT_SUPPORTED - "Combined Display feature is not supported in this platform" -* - ::CTL_RESULT_ERROR_ADAPTER_NOT_SUPPORTED_ON_LDA_SECONDARY - "Unsupported (secondary) adapter handle passed" -*/ -ctl_result_t CTL_APICALL -ctlGetSetCombinedDisplay( - ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] Handle to control device adapter - ctl_combined_display_args_t* pCombinedDisplayArgs ///< [in,out] Setup and get combined display arguments - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetSetCombinedDisplay_t pfnGetSetCombinedDisplay = (ctl_pfnGetSetCombinedDisplay_t)GetProcAddress(hinstLibPtr, "ctlGetSetCombinedDisplay"); - if (pfnGetSetCombinedDisplay) - { - result = pfnGetSetCombinedDisplay(hDeviceAdapter, pCombinedDisplayArgs); - } - } - - return result; -} - - -/** -* @brief Get/Set Display Genlock -* -* @details -* - To get or set Display Genlock. -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == hDeviceAdapter` -* + `nullptr == pGenlockArgs` -* + `nullptr == hFailureDeviceAdapter` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -* - ::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_INVALID_SIZE - "Invalid topology structure size" -* - ::CTL_RESULT_ERROR_KMD_CALL - "Kernel mode driver call failure" -*/ -ctl_result_t CTL_APICALL -ctlGetSetDisplayGenlock( - ctl_device_adapter_handle_t* hDeviceAdapter, ///< [in][release] Handle to control device adapter - ctl_genlock_args_t* pGenlockArgs, ///< [in,out] Display Genlock operation and information - uint32_t AdapterCount, ///< [in] Number of device adapters - ctl_device_adapter_handle_t* hFailureDeviceAdapter ///< [out] Handle to address the failure device adapter in an error case - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetSetDisplayGenlock_t pfnGetSetDisplayGenlock = (ctl_pfnGetSetDisplayGenlock_t)GetProcAddress(hinstLibPtr, "ctlGetSetDisplayGenlock"); - if (pfnGetSetDisplayGenlock) - { - result = pfnGetSetDisplayGenlock(hDeviceAdapter, pGenlockArgs, AdapterCount, hFailureDeviceAdapter); - } - } - - return result; -} - - -/** -* @brief Get Vblank Timestamp -* -* @details -* - To get a list of vblank timestamps in microseconds for each child -* target of a display. -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pVblankTSArgs` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" -* - ::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_t CTL_APICALL -ctlGetVblankTimestamp( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_vblank_ts_args_t* pVblankTSArgs ///< [out] Get vblank timestamp arguments - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetVblankTimestamp_t pfnGetVblankTimestamp = (ctl_pfnGetVblankTimestamp_t)GetProcAddress(hinstLibPtr, "ctlGetVblankTimestamp"); - if (pfnGetVblankTimestamp) - { - result = pfnGetVblankTimestamp(hDisplayOutput, pVblankTSArgs); - } - } - - return result; -} - - -/** -* @brief Link Display Adapters -* -* @details -* - To Link Display Adapters. -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hPrimaryAdapter` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pLdaArgs` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -* - ::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_ADAPTER_ALREADY_LINKED - "Adapter is already linked" -*/ -ctl_result_t CTL_APICALL -ctlLinkDisplayAdapters( - ctl_device_adapter_handle_t hPrimaryAdapter, ///< [in][release] Handle to Primary adapter in LDA chain - ctl_lda_args_t* pLdaArgs ///< [in] Link Display Adapters Arguments - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnLinkDisplayAdapters_t pfnLinkDisplayAdapters = (ctl_pfnLinkDisplayAdapters_t)GetProcAddress(hinstLibPtr, "ctlLinkDisplayAdapters"); - if (pfnLinkDisplayAdapters) - { - result = pfnLinkDisplayAdapters(hPrimaryAdapter, pLdaArgs); - } - } - - return result; -} - - -/** -* @brief Unlink Display Adapters -* -* @details -* - To Unlink Display Adapters -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hPrimaryAdapter` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::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_ADAPTER_NOT_SUPPORTED_ON_LDA_SECONDARY - "Unsupported (secondary) adapter handle passed" -*/ -ctl_result_t CTL_APICALL -ctlUnlinkDisplayAdapters( - ctl_device_adapter_handle_t hPrimaryAdapter ///< [in][release] Handle to Primary adapter in LDA chain - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnUnlinkDisplayAdapters_t pfnUnlinkDisplayAdapters = (ctl_pfnUnlinkDisplayAdapters_t)GetProcAddress(hinstLibPtr, "ctlUnlinkDisplayAdapters"); - if (pfnUnlinkDisplayAdapters) - { - result = pfnUnlinkDisplayAdapters(hPrimaryAdapter); - } - } - - return result; -} - - -/** -* @brief Get Linked Display Adapters -* -* @details -* - To return list of Linked Display Adapters. -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hPrimaryAdapter` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pLdaArgs` -* - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -* - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -* - ::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_ADAPTER_NOT_SUPPORTED_ON_LDA_SECONDARY - "Unsupported (secondary) adapter handle passed" -*/ -ctl_result_t CTL_APICALL -ctlGetLinkedDisplayAdapters( - ctl_device_adapter_handle_t hPrimaryAdapter, ///< [in][release] Handle to Primary adapter in LDA chain - ctl_lda_args_t* pLdaArgs ///< [out] Link Display Adapters Arguments - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetLinkedDisplayAdapters_t pfnGetLinkedDisplayAdapters = (ctl_pfnGetLinkedDisplayAdapters_t)GetProcAddress(hinstLibPtr, "ctlGetLinkedDisplayAdapters"); - if (pfnGetLinkedDisplayAdapters) - { - result = pfnGetLinkedDisplayAdapters(hPrimaryAdapter, pLdaArgs); - } - } - - return result; -} - - -/** -* @brief Get/Set Dynamic Contrast Enhancement -* -* @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 -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pDceArgs` -* - ::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 -ctlGetSetDynamicContrastEnhancement( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_dce_args_t* pDceArgs ///< [in,out] Dynamic Contrast Enhancement arguments - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetSetDynamicContrastEnhancement_t pfnGetSetDynamicContrastEnhancement = (ctl_pfnGetSetDynamicContrastEnhancement_t)GetProcAddress(hinstLibPtr, "ctlGetSetDynamicContrastEnhancement"); - if (pfnGetSetDynamicContrastEnhancement) - { - result = pfnGetSetDynamicContrastEnhancement(hDisplayOutput, pDceArgs); - } - } - - return result; -} - - -/** -* @brief Get/Set Color Format and Color Depth -* -* @details -* - 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 == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `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 -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; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetSetWireFormat_t pfnGetSetWireFormat = (ctl_pfnGetSetWireFormat_t)GetProcAddress(hinstLibPtr, "ctlGetSetWireFormat"); - if (pfnGetSetWireFormat) - { - result = pfnGetSetWireFormat(hDisplayOutput, pGetSetWireFormatSetting); - } - } - - return result; -} - - -/** -* @brief Get/Set Display settings -* -* @details -* - 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 == hDisplayOutput` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `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 -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; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetSetDisplaySettings_t pfnGetSetDisplaySettings = (ctl_pfnGetSetDisplaySettings_t)GetProcAddress(hinstLibPtr, "ctlGetSetDisplaySettings"); - if (pfnGetSetDisplaySettings) - { - result = pfnGetSetDisplaySettings(hDisplayOutput, pDisplaySettings); - } - } - - return result; -} - - -/** -* @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_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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnEccGetProperties_t pfnEccGetProperties = (ctl_pfnEccGetProperties_t)GetProcAddress(hinstLibPtr, "ctlEccGetProperties"); - if (pfnEccGetProperties) - { - result = pfnEccGetProperties(hDAhandle, pProperties); - } - } - - return result; -} - - -/** -* @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_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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnEccGetState_t pfnEccGetState = (ctl_pfnEccGetState_t)GetProcAddress(hinstLibPtr, "ctlEccGetState"); - if (pfnEccGetState) - { - result = pfnEccGetState(hDAhandle, pState); - } - } - - return result; -} - - -/** -* @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_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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnEccSetState_t pfnEccSetState = (ctl_pfnEccSetState_t)GetProcAddress(hinstLibPtr, "ctlEccSetState"); - if (pfnEccSetState) - { - result = pfnEccSetState(hDAhandle, pState); - } - } - - return result; -} - - -/** -* @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_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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnEnumEngineGroups_t pfnEnumEngineGroups = (ctl_pfnEnumEngineGroups_t)GetProcAddress(hinstLibPtr, "ctlEnumEngineGroups"); - if (pfnEnumEngineGroups) - { - result = pfnEnumEngineGroups(hDAhandle, pCount, phEngine); - } - } - - return result; -} - - -/** -* @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_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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnEngineGetProperties_t pfnEngineGetProperties = (ctl_pfnEngineGetProperties_t)GetProcAddress(hinstLibPtr, "ctlEngineGetProperties"); - if (pfnEngineGetProperties) - { - result = pfnEngineGetProperties(hEngine, pProperties); - } - } - - return result; -} - - -/** -* @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_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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnEngineGetActivity_t pfnEngineGetActivity = (ctl_pfnEngineGetActivity_t)GetProcAddress(hinstLibPtr, "ctlEngineGetActivity"); - if (pfnEngineGetActivity) - { - result = pfnEngineGetActivity(hEngine, pStats); - } - } - - return result; -} - - -/** -* @brief Get handle of fans -* -* @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 -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; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnEnumFans_t pfnEnumFans = (ctl_pfnEnumFans_t)GetProcAddress(hinstLibPtr, "ctlEnumFans"); - if (pfnEnumFans) - { - result = pfnEnumFans(hDAhandle, pCount, phFan); - } - } - - return result; -} - - -/** -* @brief Get fan 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 == hFan` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pProperties` -*/ -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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnFanGetProperties_t pfnFanGetProperties = (ctl_pfnFanGetProperties_t)GetProcAddress(hinstLibPtr, "ctlFanGetProperties"); - if (pfnFanGetProperties) - { - result = pfnFanGetProperties(hFan, pProperties); - } - } - - return result; -} - - -/** -* @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. -* - 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 == hFan` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pConfig` -*/ -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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnFanGetConfig_t pfnFanGetConfig = (ctl_pfnFanGetConfig_t)GetProcAddress(hinstLibPtr, "ctlFanGetConfig"); - if (pfnFanGetConfig) - { - result = pfnFanGetConfig(hFan, pConfig); - } - } - - return result; -} - - -/** -* @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. -* - 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 == hFan` -* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS -* + User does not have permissions to make these modifications. -*/ -ctl_result_t CTL_APICALL -ctlFanSetDefaultMode( - ctl_fan_handle_t hFan ///< [in] Handle for the component. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnFanSetDefaultMode_t pfnFanSetDefaultMode = (ctl_pfnFanSetDefaultMode_t)GetProcAddress(hinstLibPtr, "ctlFanSetDefaultMode"); - if (pfnFanSetDefaultMode) - { - result = pfnFanSetDefaultMode(hFan); - } - } - - return result; -} - - -/** -* @brief Configure the fan to rotate at a fixed speed (set mode to -* ::CTL_FAN_SPEED_MODE_FIXED) -* -* @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 == hFan` -* - 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. -*/ -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 - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnFanSetFixedSpeedMode_t pfnFanSetFixedSpeedMode = (ctl_pfnFanSetFixedSpeedMode_t)GetProcAddress(hinstLibPtr, "ctlFanSetFixedSpeedMode"); - if (pfnFanSetFixedSpeedMode) - { - result = pfnFanSetFixedSpeedMode(hFan, speed); - } - } - - return result; -} - - -/** -* @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. -* - 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 == hFan` -* - 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. -*/ -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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnFanSetSpeedTableMode_t pfnFanSetSpeedTableMode = (ctl_pfnFanSetSpeedTableMode_t)GetProcAddress(hinstLibPtr, "ctlFanSetSpeedTableMode"); - if (pfnFanSetSpeedTableMode) - { - result = pfnFanSetSpeedTableMode(hFan, speedTable); - } - } - - return result; -} - - -/** -* @brief Get current state of a fan - current mode and speed -* -* @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 == 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. -*/ -ctl_result_t CTL_APICALL -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; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnFanGetState_t pfnFanGetState = (ctl_pfnFanGetState_t)GetProcAddress(hinstLibPtr, "ctlFanGetState"); - if (pfnFanGetState) - { - result = pfnFanGetState(hFan, units, pSpeed); - } - } - - return result; -} - - -/** -* @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_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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetFirmwareProperties_t pfnGetFirmwareProperties = (ctl_pfnGetFirmwareProperties_t)GetProcAddress(hinstLibPtr, "ctlGetFirmwareProperties"); - if (pfnGetFirmwareProperties) - { - result = pfnGetFirmwareProperties(hDeviceAdapter, pProperties); - } - } - - return result; -} - - -/** -* @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_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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnEnumerateFirmwareComponents_t pfnEnumerateFirmwareComponents = (ctl_pfnEnumerateFirmwareComponents_t)GetProcAddress(hinstLibPtr, "ctlEnumerateFirmwareComponents"); - if (pfnEnumerateFirmwareComponents) - { - result = pfnEnumerateFirmwareComponents(hDeviceAdapter, pCount, phFirmware); - } - } - - return result; -} - - -/** -* @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_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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnGetFirmwareComponentProperties_t pfnGetFirmwareComponentProperties = (ctl_pfnGetFirmwareComponentProperties_t)GetProcAddress(hinstLibPtr, "ctlGetFirmwareComponentProperties"); - if (pfnGetFirmwareComponentProperties) - { - result = pfnGetFirmwareComponentProperties(hFirmware, pProperties); - } - } - - return result; -} - - -/** -* @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_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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnAllowPCIeLinkSpeedUpdate_t pfnAllowPCIeLinkSpeedUpdate = (ctl_pfnAllowPCIeLinkSpeedUpdate_t)GetProcAddress(hinstLibPtr, "ctlAllowPCIeLinkSpeedUpdate"); - if (pfnAllowPCIeLinkSpeedUpdate) - { - result = pfnAllowPCIeLinkSpeedUpdate(hDeviceAdapter, AllowPCIeLinkSpeedUpdate); - } - } - - return result; -} - - -/** -* @brief Get handle of frequency domains -* -* @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 -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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnEnumFrequencyDomains_t pfnEnumFrequencyDomains = (ctl_pfnEnumFrequencyDomains_t)GetProcAddress(hinstLibPtr, "ctlEnumFrequencyDomains"); - if (pfnEnumFrequencyDomains) - { - result = pfnEnumFrequencyDomains(hDAhandle, pCount, phFrequency); - } - } - - return result; -} - - -/** -* @brief Get frequency properties - available frequencies -* -* @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 == hFrequency` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pProperties` -*/ -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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnFrequencyGetProperties_t pfnFrequencyGetProperties = (ctl_pfnFrequencyGetProperties_t)GetProcAddress(hinstLibPtr, "ctlFrequencyGetProperties"); - if (pfnFrequencyGetProperties) - { - result = pfnFrequencyGetProperties(hFrequency, pProperties); - } - } - - return result; -} - - -/** -* @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. -* -* @returns -* - CTL_RESULT_SUCCESS -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hFrequency` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pCount` -*/ -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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnFrequencyGetAvailableClocks_t pfnFrequencyGetAvailableClocks = (ctl_pfnFrequencyGetAvailableClocks_t)GetProcAddress(hinstLibPtr, "ctlFrequencyGetAvailableClocks"); - if (pfnFrequencyGetAvailableClocks) - { - result = pfnFrequencyGetAvailableClocks(hFrequency, pCount, phFrequency); - } - } - - return result; -} - - -/** -* @brief Get current frequency limits -* -* @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 == hFrequency` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pLimits` -*/ -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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnFrequencyGetRange_t pfnFrequencyGetRange = (ctl_pfnFrequencyGetRange_t)GetProcAddress(hinstLibPtr, "ctlFrequencyGetRange"); - if (pfnFrequencyGetRange) - { - result = pfnFrequencyGetRange(hFrequency, pLimits); - } - } - - return result; -} - - -/** -* @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 == hFrequency` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pLimits` -* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS -* + User does not have permissions to make these modifications. -*/ -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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnFrequencySetRange_t pfnFrequencySetRange = (ctl_pfnFrequencySetRange_t)GetProcAddress(hinstLibPtr, "ctlFrequencySetRange"); - if (pfnFrequencySetRange) - { - result = pfnFrequencySetRange(hFrequency, pLimits); - } - } - - return result; -} - - -/** -* @brief Get current frequency state - frequency request, actual frequency, TDP -* limits -* -* @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 == hFrequency` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pState` -*/ -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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnFrequencyGetState_t pfnFrequencyGetState = (ctl_pfnFrequencyGetState_t)GetProcAddress(hinstLibPtr, "ctlFrequencyGetState"); - if (pfnFrequencyGetState) - { - result = pfnFrequencyGetState(hFrequency, pState); - } - } - - return result; -} - - -/** -* @brief Get frequency throttle time -* -* @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 == hFrequency` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pThrottleTime` -*/ -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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnFrequencyGetThrottleTime_t pfnFrequencyGetThrottleTime = (ctl_pfnFrequencyGetThrottleTime_t)GetProcAddress(hinstLibPtr, "ctlFrequencyGetThrottleTime"); - if (pfnFrequencyGetThrottleTime) - { - result = pfnFrequencyGetThrottleTime(hFrequency, pThrottleTime); - } - } - - return result; -} - - -/** -* @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_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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - 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); - } - } - - return result; -} - - -/** -* @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 -* - 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 -* - 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_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. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnOverclockPowerLimitGet_t pfnOverclockPowerLimitGet = (ctl_pfnOverclockPowerLimitGet_t)GetProcAddress(hinstLibPtr, "ctlOverclockPowerLimitGet"); - if (pfnOverclockPowerLimitGet) - { - result = pfnOverclockPowerLimitGet(hDeviceHandle, pSustainedPowerLimit); - } - } - - return result; -} - - -/** -* @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_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. - ) -{ - 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; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnOverclockResetToDefault_t pfnOverclockResetToDefault = (ctl_pfnOverclockResetToDefault_t)GetProcAddress(hinstLibPtr, "ctlOverclockResetToDefault"); - if (pfnOverclockResetToDefault) - { - result = pfnOverclockResetToDefault(hDeviceHandle); - } - } - - return result; -} - - -/** -* @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_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() - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnOverclockGpuFrequencyOffsetGetV2_t pfnOverclockGpuFrequencyOffsetGetV2 = (ctl_pfnOverclockGpuFrequencyOffsetGetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockGpuFrequencyOffsetGetV2"); - if (pfnOverclockGpuFrequencyOffsetGetV2) - { - result = pfnOverclockGpuFrequencyOffsetGetV2(hDeviceHandle, pOcFrequencyOffset); - } - } - - return result; -} - - -/** -* @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_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() - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnOverclockGpuFrequencyOffsetSetV2_t pfnOverclockGpuFrequencyOffsetSetV2 = (ctl_pfnOverclockGpuFrequencyOffsetSetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockGpuFrequencyOffsetSetV2"); - if (pfnOverclockGpuFrequencyOffsetSetV2) - { - result = pfnOverclockGpuFrequencyOffsetSetV2(hDeviceHandle, ocFrequencyOffset); - } - } - - return result; -} - - -/** -* @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_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() - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnOverclockGpuMaxVoltageOffsetGetV2_t pfnOverclockGpuMaxVoltageOffsetGetV2 = (ctl_pfnOverclockGpuMaxVoltageOffsetGetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockGpuMaxVoltageOffsetGetV2"); - if (pfnOverclockGpuMaxVoltageOffsetGetV2) - { - result = pfnOverclockGpuMaxVoltageOffsetGetV2(hDeviceHandle, pOcMaxVoltageOffset); - } - } - - return result; -} - - -/** -* @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_result_t CTL_APICALL -ctlOverclockGpuMaxVoltageOffsetSetV2( - ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - 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; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnOverclockGpuMaxVoltageOffsetSetV2_t pfnOverclockGpuMaxVoltageOffsetSetV2 = (ctl_pfnOverclockGpuMaxVoltageOffsetSetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockGpuMaxVoltageOffsetSetV2"); - if (pfnOverclockGpuMaxVoltageOffsetSetV2) - { - result = pfnOverclockGpuMaxVoltageOffsetSetV2(hDeviceHandle, ocMaxVoltageOffset); - } - } - - return result; -} - - -/** -* @brief Get the current Overclock Vram Memory Speed -* -* @details -* - 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 -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDeviceHandle` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pOcVramMemSpeedLimit` -*/ -ctl_result_t CTL_APICALL -ctlOverclockVramMemSpeedLimitGetV2( - ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - 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; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnOverclockVramMemSpeedLimitGetV2_t pfnOverclockVramMemSpeedLimitGetV2 = (ctl_pfnOverclockVramMemSpeedLimitGetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockVramMemSpeedLimitGetV2"); - if (pfnOverclockVramMemSpeedLimitGetV2) - { - result = pfnOverclockVramMemSpeedLimitGetV2(hDeviceHandle, pOcVramMemSpeedLimit); - } - } - - return result; -} - - -/** -* @brief Set the desired Overclock Vram Memory Speed -* -* @details -* - 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 -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDeviceHandle` -*/ -ctl_result_t CTL_APICALL -ctlOverclockVramMemSpeedLimitSetV2( - ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - 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; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnOverclockVramMemSpeedLimitSetV2_t pfnOverclockVramMemSpeedLimitSetV2 = (ctl_pfnOverclockVramMemSpeedLimitSetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockVramMemSpeedLimitSetV2"); - if (pfnOverclockVramMemSpeedLimitSetV2) - { - result = pfnOverclockVramMemSpeedLimitSetV2(hDeviceHandle, ocVramMemSpeedLimit); - } - } - - return result; -} - - -/** -* @brief Get the Current Sustained power limit -* -* @details -* - The purpose of this function is to read the current sustained power -* limit. -* - 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 -* - 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_result_t CTL_APICALL -ctlOverclockPowerLimitGetV2( - ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - 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; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnOverclockPowerLimitGetV2_t pfnOverclockPowerLimitGetV2 = (ctl_pfnOverclockPowerLimitGetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockPowerLimitGetV2"); - if (pfnOverclockPowerLimitGetV2) - { - result = pfnOverclockPowerLimitGetV2(hDeviceHandle, pSustainedPowerLimit); - } - } - - return result; -} - - -/** -* @brief Set the Sustained power limit -* -* @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 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 -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDeviceHandle` -*/ -ctl_result_t CTL_APICALL -ctlOverclockPowerLimitSetV2( - ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - 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; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnOverclockPowerLimitSetV2_t pfnOverclockPowerLimitSetV2 = (ctl_pfnOverclockPowerLimitSetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockPowerLimitSetV2"); - if (pfnOverclockPowerLimitSetV2) - { - result = pfnOverclockPowerLimitSetV2(hDeviceHandle, sustainedPowerLimit); - } - } - - return result; -} - - -/** -* @brief Get the current temperature limit -* -* @details -* - 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 -* - 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 -ctlOverclockTemperatureLimitGetV2( - ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - 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; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnOverclockTemperatureLimitGetV2_t pfnOverclockTemperatureLimitGetV2 = (ctl_pfnOverclockTemperatureLimitGetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockTemperatureLimitGetV2"); - if (pfnOverclockTemperatureLimitGetV2) - { - result = pfnOverclockTemperatureLimitGetV2(hDeviceHandle, pTemperatureLimit); - } - } - - return result; -} - - -/** -* @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 -* - CTL_RESULT_ERROR_UNINITIALIZED -* - CTL_RESULT_ERROR_DEVICE_LOST -* - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -* + `nullptr == hDeviceHandle` -*/ -ctl_result_t CTL_APICALL -ctlOverclockTemperatureLimitSetV2( - ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - 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; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnOverclockTemperatureLimitSetV2_t pfnOverclockTemperatureLimitSetV2 = (ctl_pfnOverclockTemperatureLimitSetV2_t)GetProcAddress(hinstLibPtr, "ctlOverclockTemperatureLimitSetV2"); - if (pfnOverclockTemperatureLimitSetV2) - { - result = pfnOverclockTemperatureLimitSetV2(hDeviceHandle, temperatureLimit); - } - } - - return result; -} - - -/** -* @brief Read VF Curve -* -* @details -* - 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 == 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 -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; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnOverclockReadVFCurve_t pfnOverclockReadVFCurve = (ctl_pfnOverclockReadVFCurve_t)GetProcAddress(hinstLibPtr, "ctlOverclockReadVFCurve"); - if (pfnOverclockReadVFCurve) - { - result = pfnOverclockReadVFCurve(hDeviceAdapter, VFCurveType, VFCurveDetail, pNumPoints, pVFCurveTable); - } - } - - return result; -} - - -/** -* @brief Write Custom VF curve -* -* @details -* - 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 == hDeviceAdapter` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pCustomVFCurveTable` -* - CTL_RESULT_ERROR_UNKNOWN - "Unknown Error" -*/ -ctl_result_t CTL_APICALL -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; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnOverclockWriteCustomVFCurve_t pfnOverclockWriteCustomVFCurve = (ctl_pfnOverclockWriteCustomVFCurve_t)GetProcAddress(hinstLibPtr, "ctlOverclockWriteCustomVFCurve"); - if (pfnOverclockWriteCustomVFCurve) - { - result = pfnOverclockWriteCustomVFCurve(hDeviceAdapter, NumPoints, pCustomVFCurveTable); - } - } - - return result; -} - - -/** -* @brief Get PCI properties - address, max speed -* -* @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_result_t CTL_APICALL -ctlPciGetProperties( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter - ctl_pci_properties_t* pProperties ///< [in,out] Will contain the PCI properties. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnPciGetProperties_t pfnPciGetProperties = (ctl_pfnPciGetProperties_t)GetProcAddress(hinstLibPtr, "ctlPciGetProperties"); - if (pfnPciGetProperties) - { - result = pfnPciGetProperties(hDAhandle, pProperties); - } - } - - return result; -} - - -/** -* @brief Get current PCI state - current speed -* -* @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_t CTL_APICALL -ctlPciGetState( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter - ctl_pci_state_t* pState ///< [in,out] Will contain the PCI properties. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnPciGetState_t pfnPciGetState = (ctl_pfnPciGetState_t)GetProcAddress(hinstLibPtr, "ctlPciGetState"); - if (pfnPciGetState) - { - result = pfnPciGetState(hDAhandle, pState); - } - } - - return result; -} - - -/** -* @brief Get handle of power domains -* -* @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 -ctlEnumPowerDomains( - 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_pwr_handle_t* phPower ///< [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_pfnEnumPowerDomains_t pfnEnumPowerDomains = (ctl_pfnEnumPowerDomains_t)GetProcAddress(hinstLibPtr, "ctlEnumPowerDomains"); - if (pfnEnumPowerDomains) - { - result = pfnEnumPowerDomains(hDAhandle, pCount, phPower); - } - } - - return result; -} - - -/** -* @brief Get properties related to a power domain -* -* @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 == hPower` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pProperties` -*/ -ctl_result_t CTL_APICALL -ctlPowerGetProperties( - ctl_pwr_handle_t hPower, ///< [in] Handle for the component. - ctl_power_properties_t* pProperties ///< [in,out] Structure that will contain property data. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnPowerGetProperties_t pfnPowerGetProperties = (ctl_pfnPowerGetProperties_t)GetProcAddress(hinstLibPtr, "ctlPowerGetProperties"); - if (pfnPowerGetProperties) - { - result = pfnPowerGetProperties(hPower, pProperties); - } - } - - return result; -} - - -/** -* @brief Get energy counter -* -* @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 == hPower` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pEnergy` -*/ -ctl_result_t CTL_APICALL -ctlPowerGetEnergyCounter( - ctl_pwr_handle_t hPower, ///< [in] Handle for the component. - ctl_power_energy_counter_t* pEnergy ///< [in,out] Will contain the latest snapshot of the energy counter and - ///< timestamp when the last counter value was measured. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnPowerGetEnergyCounter_t pfnPowerGetEnergyCounter = (ctl_pfnPowerGetEnergyCounter_t)GetProcAddress(hinstLibPtr, "ctlPowerGetEnergyCounter"); - if (pfnPowerGetEnergyCounter) - { - result = pfnPowerGetEnergyCounter(hPower, pEnergy); - } - } - - return result; -} - - -/** -* @brief Get power limits -* -* @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 == hPower` -*/ -ctl_result_t CTL_APICALL -ctlPowerGetLimits( - ctl_pwr_handle_t hPower, ///< [in] Handle for the component. - ctl_power_limits_t* pPowerLimits ///< [in,out][optional] Structure that will contain the power limits. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnPowerGetLimits_t pfnPowerGetLimits = (ctl_pfnPowerGetLimits_t)GetProcAddress(hinstLibPtr, "ctlPowerGetLimits"); - if (pfnPowerGetLimits) - { - result = pfnPowerGetLimits(hPower, pPowerLimits); - } - } - - return result; -} - - -/** -* @brief Set power limits -* -* @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 == hPower` -* - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS -* + User does not have permissions to make these modifications. -* - ::CTL_RESULT_ERROR_NOT_AVAILABLE -* + The device is in use, meaning that the GPU is under Over clocking, applying power limits under overclocking is not supported. -*/ -ctl_result_t CTL_APICALL -ctlPowerSetLimits( - ctl_pwr_handle_t hPower, ///< [in] Handle for the component. - const ctl_power_limits_t* pPowerLimits ///< [in][optional] Structure that will contain the power limits. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnPowerSetLimits_t pfnPowerSetLimits = (ctl_pfnPowerSetLimits_t)GetProcAddress(hinstLibPtr, "ctlPowerSetLimits"); - if (pfnPowerSetLimits) - { - result = pfnPowerSetLimits(hPower, pPowerLimits); - } - } - - return result; -} - - -/** -* @brief Get handle of temperature sensors -* -* @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 -ctlEnumTemperatureSensors( - 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_temp_handle_t* phTemperature ///< [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_pfnEnumTemperatureSensors_t pfnEnumTemperatureSensors = (ctl_pfnEnumTemperatureSensors_t)GetProcAddress(hinstLibPtr, "ctlEnumTemperatureSensors"); - if (pfnEnumTemperatureSensors) - { - result = pfnEnumTemperatureSensors(hDAhandle, pCount, phTemperature); - } - } - - return result; -} - - -/** -* @brief Get temperature sensor 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 == hTemperature` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pProperties` -*/ -ctl_result_t CTL_APICALL -ctlTemperatureGetProperties( - ctl_temp_handle_t hTemperature, ///< [in] Handle for the component. - ctl_temp_properties_t* pProperties ///< [in,out] Will contain the temperature sensor properties. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnTemperatureGetProperties_t pfnTemperatureGetProperties = (ctl_pfnTemperatureGetProperties_t)GetProcAddress(hinstLibPtr, "ctlTemperatureGetProperties"); - if (pfnTemperatureGetProperties) - { - result = pfnTemperatureGetProperties(hTemperature, pProperties); - } - } - - return result; -} - - -/** -* @brief Get the temperature from a specified sensor -* -* @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 == hTemperature` -* - CTL_RESULT_ERROR_INVALID_NULL_POINTER -* + `nullptr == pTemperature` -*/ -ctl_result_t CTL_APICALL -ctlTemperatureGetState( - ctl_temp_handle_t hTemperature, ///< [in] Handle for the component. - double* pTemperature ///< [in,out] Will contain the temperature read from the specified sensor - ///< in degrees Celsius. - ) -{ - ctl_result_t result = CTL_RESULT_ERROR_NOT_INITIALIZED; - - - HINSTANCE hinstLibPtr = GetLoaderHandle(); - - if (NULL != hinstLibPtr) - { - ctl_pfnTemperatureGetState_t pfnTemperatureGetState = (ctl_pfnTemperatureGetState_t)GetProcAddress(hinstLibPtr, "ctlTemperatureGetState"); - if (pfnTemperatureGetState) - { - result = pfnTemperatureGetState(hTemperature, pTemperature); - } - } - - return result; -} - - -// -// End of wrapper function implementation -// -///////////////////////////////////////////////////////////////////////////////// diff --git a/IntelPresentMon/ControlLib/igcl/IgclErrorCodeProvider.cpp b/IntelPresentMon/ControlLib/igcl/IgclErrorCodeProvider.cpp index fbaf96d9..4d79c0b2 100644 --- a/IntelPresentMon/ControlLib/igcl/IgclErrorCodeProvider.cpp +++ b/IntelPresentMon/ControlLib/igcl/IgclErrorCodeProvider.cpp @@ -5,7 +5,7 @@ using namespace pmon::util; -namespace pwr::intel +namespace pmon::tel::igcl { std::type_index IgclErrorCodeProvider::GetTargetType() const { diff --git a/IntelPresentMon/ControlLib/igcl/IgclErrorCodeProvider.h b/IntelPresentMon/ControlLib/igcl/IgclErrorCodeProvider.h index ba4146dd..995735cf 100644 --- a/IntelPresentMon/ControlLib/igcl/IgclErrorCodeProvider.h +++ b/IntelPresentMon/ControlLib/igcl/IgclErrorCodeProvider.h @@ -1,7 +1,7 @@ #pragma once #include "../../CommonUtilities/log/IErrorCodeProvider.h" -namespace pwr::intel +namespace pmon::tel::igcl { class IgclErrorCodeProvider : public pmon::util::log::IErrorCodeProvider { diff --git a/IntelPresentMon/ControlLib/igcl_api.h b/IntelPresentMon/ControlLib/igcl_api.h deleted file mode 100644 index f1fefb02..00000000 --- a/IntelPresentMon/ControlLib/igcl_api.h +++ /dev/null @@ -1,8976 +0,0 @@ -//=========================================================================== -// 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 -// not use, modify, copy, publish, distribute, disclose or transmit this software -// or the related documents without Intel's prior written permission. This software -// and the related documents are provided as is, with no express or implied -// warranties, other than those that are expressly stated in the License. -//-------------------------------------------------------------------------- - -/** - * - * @file ctl_api.h - * @version v1-r1 - * - */ -#ifndef _CTL_API_H -#define _CTL_API_H -#if defined(__cplusplus) -#pragma once -#endif - -// standard headers -#include -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -// Intel 'ctlApi' common types -#if !defined(__GNUC__) -#pragma region common -#endif -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_MAKE_VERSION -/// @brief Generates generic ::'ctlApi' API versions -#define CTL_MAKE_VERSION( _major, _minor ) (( _major << 16 )|( _minor & 0x0000ffff)) -#endif // CTL_MAKE_VERSION - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_MAJOR_VERSION -/// @brief Extracts ::'ctlApi' API major version -#define CTL_MAJOR_VERSION( _ver ) ( _ver >> 16 ) -#endif // CTL_MAJOR_VERSION - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_MINOR_VERSION -/// @brief Extracts ::'ctlApi' API minor version -#define CTL_MINOR_VERSION( _ver ) ( _ver & 0x0000ffff ) -#endif // CTL_MINOR_VERSION - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_IMPL_MAJOR_VERSION -/// @brief ::'ctlApi' API major version of this implementation -#define CTL_IMPL_MAJOR_VERSION 1 -#endif // CTL_IMPL_MAJOR_VERSION - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_IMPL_MINOR_VERSION -/// @brief ::'ctlApi' API minor version of this implementation -#define CTL_IMPL_MINOR_VERSION 1 -#endif // CTL_IMPL_MINOR_VERSION - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_IMPL_VERSION -/// @brief ::'ctlApi' API version of this implementation -#define CTL_IMPL_VERSION CTL_MAKE_VERSION( CTL_IMPL_MAJOR_VERSION, CTL_IMPL_MINOR_VERSION ) -#endif // CTL_IMPL_VERSION - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_APICALL -#if defined(_WIN32) -/// @brief Calling convention for all API functions -#define CTL_APICALL __cdecl -#else -#define CTL_APICALL -#endif // defined(_WIN32) -#endif // CTL_APICALL - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_APIEXPORT -#if defined(_WIN32) -/// @brief Microsoft-specific dllexport storage-class attribute -#define CTL_APIEXPORT __declspec(dllexport) -#else -#define CTL_APIEXPORT -#endif // defined(_WIN32) -#endif // CTL_APIEXPORT - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_DLLEXPORT -#if defined(_WIN32) -/// @brief Microsoft-specific dllexport storage-class attribute -#define CTL_DLLEXPORT __declspec(dllexport) -#endif // defined(_WIN32) -#endif // CTL_DLLEXPORT - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_DLLEXPORT -#if __GNUC__ >= 4 -/// @brief GCC-specific dllexport storage-class attribute -#define CTL_DLLEXPORT __attribute__ ((visibility ("default"))) -#else -#define CTL_DLLEXPORT -#endif // __GNUC__ >= 4 -#endif // CTL_DLLEXPORT - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_BIT -/// @brief Generic macro for enumerator bit masks -#define CTL_BIT( _i ) ( 1 << _i ) -#endif // CTL_BIT - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Supported initialization flags -typedef uint32_t ctl_init_flags_t; -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; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Version information -typedef uint32_t ctl_version_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Handle of a control API instance -typedef struct _ctl_api_handle_t *ctl_api_handle_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Handle of a device adapter instance -typedef struct _ctl_device_adapter_handle_t *ctl_device_adapter_handle_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Handle of a device temperature sensor -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; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Handle of a device fan -typedef struct _ctl_fan_handle_t *ctl_fan_handle_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Handle of a device memory module -typedef struct _ctl_mem_handle_t *ctl_mem_handle_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Handle of a device engine group -typedef struct _ctl_engine_handle_t *ctl_engine_handle_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Base for all properties types -typedef struct _ctl_base_interface_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - -} ctl_base_interface_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Value type -typedef enum _ctl_property_value_type_t -{ - CTL_PROPERTY_VALUE_TYPE_BOOL = 0, ///< Boolean - CTL_PROPERTY_VALUE_TYPE_FLOAT = 1, ///< Float - CTL_PROPERTY_VALUE_TYPE_INT32 = 2, ///< Int32 - CTL_PROPERTY_VALUE_TYPE_UINT32 = 3, ///< Unsigned Int32 - CTL_PROPERTY_VALUE_TYPE_ENUM = 4, ///< Enum - CTL_PROPERTY_VALUE_TYPE_CUSTOM = 5, ///< Custom argument - CTL_PROPERTY_VALUE_TYPE_MAX - -} ctl_property_value_type_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Property range details, a generic struct to hold min/max/step size -/// information of various feature properties -typedef struct _ctl_property_range_info_t -{ - float min_possible_value; ///< [out] Minimum possible value - float max_possible_value; ///< [out] Maximum possible value - float step_size; ///< [out] Step size possible - float default_value; ///< [out] Default value - -} ctl_property_range_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Property range details of integer type, a generic struct to hold -/// min/max/step size information of various feature properties -typedef struct _ctl_property_range_info_int_t -{ - int32_t min_possible_value; ///< [out] Minimum possible value - int32_t max_possible_value; ///< [out] Maximum possible value - int32_t step_size; ///< [out] Step size possible - int32_t default_value; ///< [out] Default value - -} ctl_property_range_info_int_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Property range details of unsigned integer type, a generic struct to -/// hold min/max/step size information of various feature properties -typedef struct _ctl_property_range_info_uint_t -{ - uint32_t min_possible_value; ///< [out] Minimum possible value - uint32_t max_possible_value; ///< [out] Maximum possible value - uint32_t step_size; ///< [out] Step size possible - uint32_t default_value; ///< [out] Default value - -} ctl_property_range_info_uint_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Bool feature details -typedef struct _ctl_property_info_boolean_t -{ - bool DefaultState; ///< [out] Default state - -} ctl_property_info_boolean_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Bool feature for get/set -typedef struct _ctl_property_boolean_t -{ - bool Enable; ///< [in,out] Enable - -} ctl_property_boolean_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Enumeration feature details -typedef struct _ctl_property_info_enum_t -{ - uint64_t SupportedTypes; ///< [out] Supported possible values represented as a bitmask - uint32_t DefaultType; ///< [out] Default type - -} ctl_property_info_enum_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Enumeration feature for get/set -typedef struct _ctl_property_enum_t -{ - uint32_t EnableType; ///< [in,out] Enable with specific type - -} ctl_property_enum_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Float feature details -typedef struct _ctl_property_info_float_t -{ - bool DefaultEnable; ///< [in,out] DefaultEnable - ctl_property_range_info_t RangeInfo; ///< [out] Min/max/default/step details - -} ctl_property_info_float_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Float feature for get/set -typedef struct _ctl_property_float_t -{ - bool Enable; ///< [in,out] Enable - float Value; ///< [in,out] Value - -} ctl_property_float_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Int32 feature details -typedef struct _ctl_property_info_int_t -{ - bool DefaultEnable; ///< [in,out] DefaultEnable - ctl_property_range_info_int_t RangeInfo; ///< [out] Min/max/default/step details - -} ctl_property_info_int_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Int32 feature for get/set -typedef struct _ctl_property_int_t -{ - bool Enable; ///< [in,out] Enable - int32_t Value; ///< [in,out] Value - -} ctl_property_int_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Int32 feature details -typedef struct _ctl_property_info_uint_t -{ - bool DefaultEnable; ///< [in,out] DefaultEnable - ctl_property_range_info_uint_t RangeInfo; ///< [out] Min/max/default/step details - -} ctl_property_info_uint_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Int32 feature for get/set -typedef struct _ctl_property_uint_t -{ - bool Enable; ///< [in,out] Enable - uint32_t Value; ///< [in,out] Value - -} ctl_property_uint_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Feature element details, union of bool/float/enum property_info -/// structs. Used for feature specific capability check -typedef union _ctl_property_info_t -{ - ctl_property_info_boolean_t BoolType; ///< [in,out] Boolean type fields - ctl_property_info_float_t FloatType; ///< [in,out] Float type fields - ctl_property_info_int_t IntType; ///< [in,out] Int type fields - ctl_property_info_enum_t EnumType; ///< [in,out] Enum type fields - ctl_property_info_uint_t UIntType; ///< [in,out] Unsigned Int type fields - -} ctl_property_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Feature element details, union of bool/float/enum property structs. -/// Used for get/set calls -typedef union _ctl_property_t -{ - ctl_property_boolean_t BoolType; ///< [in,out] Boolean type fields - ctl_property_float_t FloatType; ///< [in,out] Float type fields - ctl_property_int_t IntType; ///< [in,out] Int type fields - ctl_property_enum_t EnumType; ///< [in,out] Enum type fields - ctl_property_uint_t UIntType; ///< [in,out] Unsigned Int type fields - -} ctl_property_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Defines Return/Error codes. -/// All generic error (bit30) codes are between 0x40000000-0x4000FFFF. -/// All 3D (bit 29) specific error codes are between 0x60000000-0x6000FFFF. -/// All media (bit 28) specific error codes are between 0x50000000-0x5000FFFF. -/// All display (bit 27) specific error codes are between 0x48000000-0x4800FFFF -/// All core (bit 26) specific error codes are between 0x44000000-0x4400FFFF -/// Success result code with additional info are between 0x00000001-0x0000FFFF. -typedef enum _ctl_result_t -{ - CTL_RESULT_SUCCESS = 0x00000000, ///< success - CTL_RESULT_SUCCESS_STILL_OPEN_BY_ANOTHER_CALLER = 0x00000001, ///< success but still open by another caller - CTL_RESULT_ERROR_SUCCESS_END = 0x0000FFFF, ///< "Success group error code end value, not to be used - ///< " - CTL_RESULT_ERROR_GENERIC_START = 0x40000000, ///< Generic error code starting value, not to be used - CTL_RESULT_ERROR_NOT_INITIALIZED = 0x40000001, ///< Result not initialized - CTL_RESULT_ERROR_ALREADY_INITIALIZED = 0x40000002, ///< Already initialized - CTL_RESULT_ERROR_DEVICE_LOST = 0x40000003, ///< Device hung, reset, was removed, or driver update occurred - CTL_RESULT_ERROR_OUT_OF_HOST_MEMORY = 0x40000004, ///< Insufficient host memory to satisfy call - CTL_RESULT_ERROR_OUT_OF_DEVICE_MEMORY = 0x40000005, ///< Insufficient device memory to satisfy call - CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS = 0x40000006, ///< Access denied due to permission level - CTL_RESULT_ERROR_NOT_AVAILABLE = 0x40000007, ///< Resource was removed - CTL_RESULT_ERROR_UNINITIALIZED = 0x40000008, ///< Library not initialized - CTL_RESULT_ERROR_UNSUPPORTED_VERSION = 0x40000009, ///< Generic error code for unsupported versions - CTL_RESULT_ERROR_UNSUPPORTED_FEATURE = 0x4000000a, ///< Generic error code for unsupported features - CTL_RESULT_ERROR_INVALID_ARGUMENT = 0x4000000b, ///< Generic error code for invalid arguments - CTL_RESULT_ERROR_INVALID_API_HANDLE = 0x4000000c, ///< API handle in invalid - CTL_RESULT_ERROR_INVALID_NULL_HANDLE = 0x4000000d, ///< Handle argument is not valid - CTL_RESULT_ERROR_INVALID_NULL_POINTER = 0x4000000e, ///< Pointer argument may not be nullptr - CTL_RESULT_ERROR_INVALID_SIZE = 0x4000000f, ///< Size argument is invalid (e.g., must not be zero) - CTL_RESULT_ERROR_UNSUPPORTED_SIZE = 0x40000010, ///< Size argument is not supported by the device (e.g., too large) - CTL_RESULT_ERROR_UNSUPPORTED_IMAGE_FORMAT = 0x40000011, ///< Image format is not supported by the device - CTL_RESULT_ERROR_DATA_READ = 0x40000012, ///< Data read error - CTL_RESULT_ERROR_DATA_WRITE = 0x40000013, ///< Data write error - CTL_RESULT_ERROR_DATA_NOT_FOUND = 0x40000014, ///< Data not found error - CTL_RESULT_ERROR_NOT_IMPLEMENTED = 0x40000015, ///< Function not implemented - CTL_RESULT_ERROR_OS_CALL = 0x40000016, ///< Operating system call failure - CTL_RESULT_ERROR_KMD_CALL = 0x40000017, ///< Kernel mode driver call failure - CTL_RESULT_ERROR_UNLOAD = 0x40000018, ///< Library unload failure - CTL_RESULT_ERROR_ZE_LOADER = 0x40000019, ///< Level0 loader not found - CTL_RESULT_ERROR_INVALID_OPERATION_TYPE = 0x4000001a, ///< Invalid operation type - CTL_RESULT_ERROR_NULL_OS_INTERFACE = 0x4000001b,///< Null OS interface - CTL_RESULT_ERROR_NULL_OS_ADAPATER_HANDLE = 0x4000001c, ///< Null OS adapter handle - CTL_RESULT_ERROR_NULL_OS_DISPLAY_OUTPUT_HANDLE = 0x4000001d,///< Null display output handle - CTL_RESULT_ERROR_WAIT_TIMEOUT = 0x4000001e, ///< Timeout in Wait function - CTL_RESULT_ERROR_PERSISTANCE_NOT_SUPPORTED = 0x4000001f,///< Persistance not supported - CTL_RESULT_ERROR_PLATFORM_NOT_SUPPORTED = 0x40000020, ///< Platform not supported - CTL_RESULT_ERROR_UNKNOWN_APPLICATION_UID = 0x40000021, ///< Unknown Appplicaion UID in Initialization call - CTL_RESULT_ERROR_INVALID_ENUMERATION = 0x40000022, ///< The enum is not valid - CTL_RESULT_ERROR_FILE_DELETE = 0x40000023, ///< Error in file delete operation - CTL_RESULT_ERROR_RESET_DEVICE_REQUIRED = 0x40000024,///< The device requires a reset. - CTL_RESULT_ERROR_FULL_REBOOT_REQUIRED = 0x40000025, ///< The device requires a full reboot. - 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 - CTL_RESULT_ERROR_CORE_OVERCLOCK_NOT_SUPPORTED = 0x44000001, ///< The Overclock is not supported. - 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 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 - CTL_RESULT_ERROR_3D_END = 0x6000FFFF, ///< "3D error code end value, not to be used - ///< " - CTL_RESULT_ERROR_MEDIA_START = 0x50000000, ///< Media error code starting value, not to be used - CTL_RESULT_ERROR_MEDIA_END = 0x5000FFFF, ///< "Media error code end value, not to be used - ///< " - CTL_RESULT_ERROR_DISPLAY_START = 0x48000000, ///< Display error code starting value, not to be used - CTL_RESULT_ERROR_INVALID_AUX_ACCESS_FLAG = 0x48000001, ///< Invalid flag for Aux access - CTL_RESULT_ERROR_INVALID_SHARPNESS_FILTER_FLAG = 0x48000002,///< Invalid flag for Sharpness - CTL_RESULT_ERROR_DISPLAY_NOT_ATTACHED = 0x48000003, ///< Error for Display not attached - CTL_RESULT_ERROR_DISPLAY_NOT_ACTIVE = 0x48000004, ///< Error for display attached but not active - CTL_RESULT_ERROR_INVALID_POWERFEATURE_OPTIMIZATION_FLAG = 0x48000005, ///< Error for invalid power optimization flag - CTL_RESULT_ERROR_INVALID_POWERSOURCE_TYPE_FOR_DPST = 0x48000006,///< DPST is supported only in DC Mode - CTL_RESULT_ERROR_INVALID_PIXTX_GET_CONFIG_QUERY_TYPE = 0x48000007, ///< Invalid query type for pixel transformation get configuration - CTL_RESULT_ERROR_INVALID_PIXTX_SET_CONFIG_OPERATION_TYPE = 0x48000008, ///< Invalid operation type for pixel transformation set configuration - CTL_RESULT_ERROR_INVALID_SET_CONFIG_NUMBER_OF_SAMPLES = 0x48000009, ///< Invalid number of samples for pixel transformation set configuration - CTL_RESULT_ERROR_INVALID_PIXTX_BLOCK_ID = 0x4800000a, ///< Invalid block id for pixel transformation - CTL_RESULT_ERROR_INVALID_PIXTX_BLOCK_TYPE = 0x4800000b, ///< Invalid block type for pixel transformation - CTL_RESULT_ERROR_INVALID_PIXTX_BLOCK_NUMBER = 0x4800000c, ///< Invalid block number for pixel transformation - CTL_RESULT_ERROR_INSUFFICIENT_PIXTX_BLOCK_CONFIG_MEMORY = 0x4800000d, ///< Insufficient memery allocated for BlockConfigs - CTL_RESULT_ERROR_3DLUT_INVALID_PIPE = 0x4800000e, ///< Invalid pipe for 3dlut - CTL_RESULT_ERROR_3DLUT_INVALID_DATA = 0x4800000f, ///< Invalid 3dlut data - CTL_RESULT_ERROR_3DLUT_NOT_SUPPORTED_IN_HDR = 0x48000010, ///< 3dlut not supported in HDR - CTL_RESULT_ERROR_3DLUT_INVALID_OPERATION = 0x48000011, ///< Invalid 3dlut operation - CTL_RESULT_ERROR_3DLUT_UNSUCCESSFUL = 0x48000012, ///< 3dlut call unsuccessful - CTL_RESULT_ERROR_AUX_DEFER = 0x48000013, ///< AUX defer failure - CTL_RESULT_ERROR_AUX_TIMEOUT = 0x48000014, ///< AUX timeout failure - CTL_RESULT_ERROR_AUX_INCOMPLETE_WRITE = 0x48000015, ///< AUX incomplete write failure - CTL_RESULT_ERROR_I2C_AUX_STATUS_UNKNOWN = 0x48000016, ///< I2C/AUX unkonown failure - CTL_RESULT_ERROR_I2C_AUX_UNSUCCESSFUL = 0x48000017, ///< I2C/AUX unsuccessful - CTL_RESULT_ERROR_LACE_INVALID_DATA_ARGUMENT_PASSED = 0x48000018,///< Lace Incorrrect AggressivePercent data or LuxVsAggressive Map data - ///< passed by user - CTL_RESULT_ERROR_EXTERNAL_DISPLAY_ATTACHED = 0x48000019,///< External Display is Attached hence fail the Display Switch - CTL_RESULT_ERROR_CUSTOM_MODE_STANDARD_CUSTOM_MODE_EXISTS = 0x4800001a, ///< Standard custom mode exists - CTL_RESULT_ERROR_CUSTOM_MODE_NON_CUSTOM_MATCHING_MODE_EXISTS = 0x4800001b, ///< Non custom matching mode exists - CTL_RESULT_ERROR_CUSTOM_MODE_INSUFFICIENT_MEMORY = 0x4800001c, ///< Custom mode insufficent memory - CTL_RESULT_ERROR_ADAPTER_ALREADY_LINKED = 0x4800001d, ///< Adapter is already linked - CTL_RESULT_ERROR_ADAPTER_NOT_IDENTICAL = 0x4800001e,///< Adapter is not identical for linking - CTL_RESULT_ERROR_ADAPTER_NOT_SUPPORTED_ON_LDA_SECONDARY = 0x4800001f, ///< Adapter is LDA Secondary, so not supporting requested operation - CTL_RESULT_ERROR_SET_FBC_FEATURE_NOT_SUPPORTED = 0x48000020,///< Set FBC Feature not supported - CTL_RESULT_ERROR_DISPLAY_END = 0x4800FFFF, ///< "Display error code end value, not to be used - ///< " - CTL_RESULT_MAX - -} ctl_result_t; - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_MAX_DEVICE_NAME_LEN -/// @brief Maximum IPC handle size -#define CTL_MAX_DEVICE_NAME_LEN 100 -#endif // CTL_MAX_DEVICE_NAME_LEN - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_MAX_RESERVED_SIZE -/// @brief Maximum reserved size for future members. -#define CTL_MAX_RESERVED_SIZE 108 -#endif // CTL_MAX_RESERVED_SIZE - -/////////////////////////////////////////////////////////////////////////////// -/// @brief General Physical Units. -typedef enum _ctl_units_t -{ - CTL_UNITS_FREQUENCY_MHZ = 0, ///< Type is Frequency with units in MHz. - CTL_UNITS_OPERATIONS_GTS = 1, ///< Type is Frequency with units in GT/s (gigatransfers per second). - CTL_UNITS_OPERATIONS_MTS = 2, ///< Type is Frequency with units in MT/s (megatransfers per second). - CTL_UNITS_VOLTAGE_VOLTS = 3, ///< Type is Voltage with units in Volts. - CTL_UNITS_POWER_WATTS = 4, ///< Type is Power with units in Watts. - CTL_UNITS_TEMPERATURE_CELSIUS = 5, ///< Type is Temperature with units in Celsius. - CTL_UNITS_ENERGY_JOULES = 6, ///< Type is Energy with units in Joules. - CTL_UNITS_TIME_SECONDS = 7, ///< Type is Time with units in Seconds. - CTL_UNITS_MEMORY_BYTES = 8, ///< Type is Memory with units in Bytes. - 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 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 - -} ctl_units_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief General Data Types. -typedef enum _ctl_data_type_t -{ - CTL_DATA_TYPE_INT8 = 0, ///< The data type is 8 bit signed integer. - CTL_DATA_TYPE_UINT8 = 1, ///< The data type is 8 bit unsigned integer. - CTL_DATA_TYPE_INT16 = 2, ///< The data type is 16 bit signed integer. - CTL_DATA_TYPE_UINT16 = 3, ///< The data type is 16 bit unsigned integer. - CTL_DATA_TYPE_INT32 = 4, ///< The data type is 32 bit signed integer. - CTL_DATA_TYPE_UINT32 = 5, ///< The data type is 32 bit unsigned integer. - CTL_DATA_TYPE_INT64 = 6, ///< The data type is 64 bit signed integer. - CTL_DATA_TYPE_UINT64 = 7, ///< The data type is 64 bit unsigned integer. - CTL_DATA_TYPE_FLOAT = 8, ///< The data type is 32 bit floating point. - CTL_DATA_TYPE_DOUBLE = 9, ///< The data type is 64 bit floating point. - CTL_DATA_TYPE_STRING_ASCII = 10, ///< The data type is an array of 8 bit unsigned integers. - CTL_DATA_TYPE_STRING_UTF16 = 11, ///< The data type is an array of 16 bit unsigned integers. - CTL_DATA_TYPE_STRING_UTF132 = 12, ///< The data type is an array of 32 bit unsigned integers. - CTL_DATA_TYPE_UNKNOWN = 0x4800FFFF, ///< The data type is unknown. - CTL_DATA_TYPE_MAX - -} ctl_data_type_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Union for Generic Data. -/// -/// @details -/// - The telemetry data items could be of different types. -/// - Refer to ::ctl_data_type_t to find the current type. -typedef union _ctl_data_value_t -{ - int8_t data8; ///< [out] The data type is 8 bit signed integer. - uint8_t datau8; ///< [out] The data type is 8 bit unsigned integer. - int16_t data16; ///< [out] The data type is 16 bit signed integer. - uint16_t datau16; ///< [out] The data type is 16 bit unsigned integer. - int32_t data32; ///< [out] The data type is 32 bit signed integer. - uint32_t datau32; ///< [out] The data type is 32 bit unsigned integer. - int64_t data64; ///< [out] The data type is 64 bit signed integer. - uint64_t datau64; ///< [out] The data type is 64 bit unsigned integer. - float datafloat; ///< [out] The data type is 32 bit floating point. - double datadouble; ///< [out] The data type is 64 bit floating point. - -} ctl_data_value_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Base for all properties types -typedef struct _ctl_base_properties_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - -} ctl_base_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Application Unique ID -typedef struct _ctl_application_id_t -{ - uint32_t Data1; ///< [in] Data1 - uint16_t Data2; ///< [in] Data2 - uint16_t Data3; ///< [in] Data3 - uint8_t Data4[8]; ///< [in] Data4 - -} ctl_application_id_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Init arguments -typedef struct _ctl_init_args_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_version_info_t AppVersion; ///< [in][release] App's IGCL version - ctl_init_flags_t flags; ///< [in][release] Caller version - ctl_version_info_t SupportedVersion; ///< [out][release] IGCL implementation version - ctl_application_id_t ApplicationUID; ///< [in] Application Provided Unique ID.Application can pass all 0's as - ///< the default ID - -} ctl_init_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Reserved struct -typedef struct _ctl_reserved_args_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - void* pSpecialArg; ///< [in] Reserved struct - uint32_t ArgSize; ///< [in] struct size - -} ctl_reserved_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Reserved base struct -typedef struct _ctl_reserved_args_base_t -{ - ctl_application_id_t ReservedFuncID; ///< [in] Unique ID for reserved/special function - -} ctl_reserved_args_base_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Reserved - Unlock function capability -typedef struct _ctl_unlock_capability_t -{ - ctl_application_id_t ReservedFuncID; ///< [in] Unique ID for reserved/special function - ctl_application_id_t UnlockCapsID; ///< [in] Unique ID to unlock a specific function - -} ctl_unlock_capability_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Used by loader like modules to specify runtime implementation details -typedef struct _ctl_runtime_path_args_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_application_id_t UnlockID; ///< [in] Unique ID for reserved/special function - wchar_t* pRuntimePath; ///< [in] Path to runtime DLL - uint16_t DeviceID; ///< [in] Device ID of interest to caller. pRuntimePath should not be NULL. - uint8_t RevID; ///< [in] Revision ID of interest to caller. pRuntimePath should not be - ///< NULL. - -} ctl_runtime_path_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Control Api Init -/// -/// @details -/// - Control Api Init -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pInitDesc` -/// + `nullptr == phAPIHandle` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlInit( - ctl_init_args_t* pInitDesc, ///< [in][out] App's control API version - ctl_api_handle_t* phAPIHandle ///< [in][out][release] Control API handle - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Control Api Destroy -/// -/// @details -/// - Control Api Close -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hAPIHandle` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlClose( - ctl_api_handle_t hAPIHandle ///< [in][release] Control API implementation handle obtained during init - ///< call - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Runtime path -/// -/// @details -/// - Control Api set runtime path. Optional call from a loader which allows -/// the loaded runtime to enumerate only the adapters which the specified -/// runtime is responsible for. This is done usually by a loader or by -/// callers who know how to get the specific runtime of interest. This -/// call right now is reserved for use by Intel components. -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pArgs` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlSetRuntimePath( - ctl_runtime_path_args_t* pArgs ///< [in] Runtime path - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Supported Functions -typedef uint32_t ctl_supported_functions_flags_t; -typedef enum _ctl_supported_functions_flag_t -{ - CTL_SUPPORTED_FUNCTIONS_FLAG_DISPLAY = CTL_BIT(0), ///< [out] Is Display supported - CTL_SUPPORTED_FUNCTIONS_FLAG_3D = CTL_BIT(1), ///< [out] Is 3D supported - CTL_SUPPORTED_FUNCTIONS_FLAG_MEDIA = CTL_BIT(2),///< [out] Is Media supported - CTL_SUPPORTED_FUNCTIONS_FLAG_MAX = 0x80000000 - -} ctl_supported_functions_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Firmware version -typedef struct _ctl_firmware_version_t -{ - uint64_t major_version; ///< [out] Major version - uint64_t minor_version; ///< [out] Minor version - uint64_t build_number; ///< [out] Build number - -} ctl_firmware_version_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief DeviceType -typedef enum _ctl_device_type_t -{ - CTL_DEVICE_TYPE_GRAPHICS = 1, ///< Graphics Device type - CTL_DEVICE_TYPE_SYSTEM = 2, ///< System Device type - CTL_DEVICE_TYPE_MAX - -} ctl_device_type_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Adapter Properties -typedef uint32_t ctl_adapter_properties_flags_t; -typedef enum _ctl_adapter_properties_flag_t -{ - CTL_ADAPTER_PROPERTIES_FLAG_INTEGRATED = CTL_BIT(0),///< [out] Is Integrated Graphics adapter - CTL_ADAPTER_PROPERTIES_FLAG_LDA_PRIMARY = CTL_BIT(1), ///< [out] Is Primary (Lead) adapter in a Linked Display Adapter (LDA) - ///< chain - CTL_ADAPTER_PROPERTIES_FLAG_LDA_SECONDARY = CTL_BIT(2), ///< [out] Is Secondary (Linked) adapter in a Linked Display Adapter (LDA) - ///< chain - CTL_ADAPTER_PROPERTIES_FLAG_MAX = 0x80000000 - -} ctl_adapter_properties_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Adapter Pci Bus, Device, Function -typedef struct _ctl_adapter_bdf_t -{ - uint8_t bus; ///< [out] PCI Bus Number - uint8_t device; ///< [out] PCI device number - uint8_t function; ///< [out] PCI function - -} ctl_adapter_bdf_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Device Adapter properties -typedef struct _ctl_device_adapter_properties_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - void* pDeviceID; ///< [in,out] OS specific Device ID - uint32_t device_id_size; ///< [in] size of the device ID - 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] 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 - uint32_t num_eus_per_sub_slice; ///< [out] Number of EUs per sub-slice - uint32_t num_sub_slices_per_slice; ///< [out] Number of sub-slices per slice - 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] 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; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief OperationType -typedef enum _ctl_operation_type_t -{ - CTL_OPERATION_TYPE_READ = 1, ///< Read operation - CTL_OPERATION_TYPE_WRITE = 2, ///< Write operation - CTL_OPERATION_TYPE_MAX - -} ctl_operation_type_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Generic Structure for Void* datatypes -typedef struct _ctl_generic_void_datatype_t -{ - void* pData; ///< [in,out]void pointer to memory - uint32_t size; ///< [in,out]size of the allocated memory - -} ctl_generic_void_datatype_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Generic Structure for Revision datatypes -typedef struct _ctl_revision_datatype_t -{ - uint8_t major_version; ///< [in,out]Major Version - uint8_t minor_version; ///< [in,out]Minor Version - uint8_t revision_version; ///< [in,out]Revision Version - -} ctl_revision_datatype_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Property Type flags -typedef uint32_t ctl_property_type_flags_t; -typedef enum _ctl_property_type_flag_t -{ - CTL_PROPERTY_TYPE_FLAG_DISPLAY = CTL_BIT(0), ///< Display type. Supported scenarios: Sharpness/gamma/CSC - CTL_PROPERTY_TYPE_FLAG_3D = CTL_BIT(1), ///< 3D type. Supported scenarios: All set calls via IGCL's 3D APIs - CTL_PROPERTY_TYPE_FLAG_MEDIA = CTL_BIT(2), ///< Media type. Supported scenarios: All set calls via IGCL's media APIs - CTL_PROPERTY_TYPE_FLAG_CORE = CTL_BIT(3), ///< For future: Core graphic event types like clocking, frequency etc. - CTL_PROPERTY_TYPE_FLAG_MAX = 0x80000000 - -} ctl_property_type_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Arguments related to wait for a property change function -typedef struct _ctl_wait_property_change_args_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_property_type_flags_t PropertyType; ///< [in] Type of the property - uint32_t TimeOutMilliSec; ///< [in][release] Time-out interval in milliseconds. Specify 0xFFFFFFFF if - ///< time-out is not desired - uint32_t EventMiscFlags; ///< [in][release] Event flags for future use - void* pReserved; ///< [in][release] Reserved for future use - uint64_t ReservedOutFlags; ///< [out] Reserved out argument for future use - -} ctl_wait_property_change_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Display orientation (rotation) -typedef enum _ctl_display_orientation_t -{ - CTL_DISPLAY_ORIENTATION_0 = 0, ///< 0 Degree - CTL_DISPLAY_ORIENTATION_90 = 1, ///< 90 Degree - CTL_DISPLAY_ORIENTATION_180 = 2, ///< 180 Degree - CTL_DISPLAY_ORIENTATION_270 = 3, ///< 270 Degree - CTL_DISPLAY_ORIENTATION_MAX - -} ctl_display_orientation_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Rectangle -typedef struct _ctl_rect_t -{ - int32_t Left; ///< [in,out] Left - int32_t Top; ///< [in,out] Top - int32_t Right; ///< [in,out] Right - int32_t Bottom; ///< [in,out] Bottom - -} ctl_rect_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Wait for a property change. Note that this is a blocking call -/// -/// @details -/// - Wait for a property change in display, 3d, media etc. -/// -/// @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 == pArgs` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlWaitForPropertyChange( - ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter - ctl_wait_property_change_args_t* pArgs ///< [in] Argument containing information about which property changes to - ///< listen for - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Reserved function -/// -/// @details -/// - Reserved function -/// -/// @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 == pArgs` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlReservedCall( - ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter - ctl_reserved_args_t* pArgs ///< [in] Argument containing information - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_base_interface_t -typedef struct _ctl_base_interface_t ctl_base_interface_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_property_range_info_t -typedef struct _ctl_property_range_info_t ctl_property_range_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_property_range_info_int_t -typedef struct _ctl_property_range_info_int_t ctl_property_range_info_int_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_property_range_info_uint_t -typedef struct _ctl_property_range_info_uint_t ctl_property_range_info_uint_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_property_info_boolean_t -typedef struct _ctl_property_info_boolean_t ctl_property_info_boolean_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_property_boolean_t -typedef struct _ctl_property_boolean_t ctl_property_boolean_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_property_info_enum_t -typedef struct _ctl_property_info_enum_t ctl_property_info_enum_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_property_enum_t -typedef struct _ctl_property_enum_t ctl_property_enum_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_property_info_float_t -typedef struct _ctl_property_info_float_t ctl_property_info_float_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_property_float_t -typedef struct _ctl_property_float_t ctl_property_float_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_property_info_int_t -typedef struct _ctl_property_info_int_t ctl_property_info_int_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_property_int_t -typedef struct _ctl_property_int_t ctl_property_int_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_property_info_uint_t -typedef struct _ctl_property_info_uint_t ctl_property_info_uint_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_property_uint_t -typedef struct _ctl_property_uint_t ctl_property_uint_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_base_properties_t -typedef struct _ctl_base_properties_t ctl_base_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_application_id_t -typedef struct _ctl_application_id_t ctl_application_id_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_init_args_t -typedef struct _ctl_init_args_t ctl_init_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_reserved_args_t -typedef struct _ctl_reserved_args_t ctl_reserved_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_reserved_args_base_t -typedef struct _ctl_reserved_args_base_t ctl_reserved_args_base_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_unlock_capability_t -typedef struct _ctl_unlock_capability_t ctl_unlock_capability_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_runtime_path_args_t -typedef struct _ctl_runtime_path_args_t ctl_runtime_path_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_firmware_version_t -typedef struct _ctl_firmware_version_t ctl_firmware_version_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_adapter_bdf_t -typedef struct _ctl_adapter_bdf_t ctl_adapter_bdf_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_device_adapter_properties_t -typedef struct _ctl_device_adapter_properties_t ctl_device_adapter_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_generic_void_datatype_t -typedef struct _ctl_generic_void_datatype_t ctl_generic_void_datatype_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_revision_datatype_t -typedef struct _ctl_revision_datatype_t ctl_revision_datatype_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_wait_property_change_args_t -typedef struct _ctl_wait_property_change_args_t ctl_wait_property_change_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_rect_t -typedef struct _ctl_rect_t ctl_rect_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_endurance_gaming_caps_t -typedef struct _ctl_endurance_gaming_caps_t ctl_endurance_gaming_caps_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_endurance_gaming_t -typedef struct _ctl_endurance_gaming_t ctl_endurance_gaming_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_endurance_gaming2_t -typedef struct _ctl_endurance_gaming2_t ctl_endurance_gaming2_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_adaptivesync_caps_t -typedef struct _ctl_adaptivesync_caps_t ctl_adaptivesync_caps_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_adaptivesync_getset_t -typedef struct _ctl_adaptivesync_getset_t ctl_adaptivesync_getset_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_3d_app_profiles_caps_t -typedef struct _ctl_3d_app_profiles_caps_t ctl_3d_app_profiles_caps_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_3d_app_profiles_t -typedef struct _ctl_3d_app_profiles_t ctl_3d_app_profiles_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_3d_tier_details_t -typedef struct _ctl_3d_tier_details_t ctl_3d_tier_details_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_3d_feature_details_t -typedef struct _ctl_3d_feature_details_t ctl_3d_feature_details_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_3d_feature_caps_t -typedef struct _ctl_3d_feature_caps_t ctl_3d_feature_caps_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_3d_feature_getset_t -typedef struct _ctl_3d_feature_getset_t ctl_3d_feature_getset_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_kmd_load_features_t -typedef struct _ctl_kmd_load_features_t ctl_kmd_load_features_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_display_timing_t -typedef struct _ctl_display_timing_t ctl_display_timing_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_display_properties_t -typedef struct _ctl_display_properties_t ctl_display_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_adapter_display_encoder_properties_t -typedef struct _ctl_adapter_display_encoder_properties_t ctl_adapter_display_encoder_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_sharpness_filter_properties_t -typedef struct _ctl_sharpness_filter_properties_t ctl_sharpness_filter_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_sharpness_caps_t -typedef struct _ctl_sharpness_caps_t ctl_sharpness_caps_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_sharpness_settings_t -typedef struct _ctl_sharpness_settings_t ctl_sharpness_settings_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_i2c_access_args_t -typedef struct _ctl_i2c_access_args_t ctl_i2c_access_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_i2c_access_pinpair_args_t -typedef struct _ctl_i2c_access_pinpair_args_t ctl_i2c_access_pinpair_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_aux_access_args_t -typedef struct _ctl_aux_access_args_t ctl_aux_access_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_power_optimization_caps_t -typedef struct _ctl_power_optimization_caps_t ctl_power_optimization_caps_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_power_optimization_lrr_t -typedef struct _ctl_power_optimization_lrr_t ctl_power_optimization_lrr_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_power_optimization_psr_t -typedef struct _ctl_power_optimization_psr_t ctl_power_optimization_psr_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_power_optimization_dpst_t -typedef struct _ctl_power_optimization_dpst_t ctl_power_optimization_dpst_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_power_optimization_settings_t -typedef struct _ctl_power_optimization_settings_t ctl_power_optimization_settings_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_set_brightness_t -typedef struct _ctl_set_brightness_t ctl_set_brightness_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_get_brightness_t -typedef struct _ctl_get_brightness_t ctl_get_brightness_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_pixtx_color_primaries_t -typedef struct _ctl_pixtx_color_primaries_t ctl_pixtx_color_primaries_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_pixtx_pixel_format_t -typedef struct _ctl_pixtx_pixel_format_t ctl_pixtx_pixel_format_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_pixtx_1dlut_config_t -typedef struct _ctl_pixtx_1dlut_config_t ctl_pixtx_1dlut_config_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_pixtx_matrix_config_t -typedef struct _ctl_pixtx_matrix_config_t ctl_pixtx_matrix_config_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_pixtx_3dlut_sample_t -typedef struct _ctl_pixtx_3dlut_sample_t ctl_pixtx_3dlut_sample_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_pixtx_3dlut_config_t -typedef struct _ctl_pixtx_3dlut_config_t ctl_pixtx_3dlut_config_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_pixtx_block_config_t -typedef struct _ctl_pixtx_block_config_t ctl_pixtx_block_config_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_pixtx_pipe_get_config_t -typedef struct _ctl_pixtx_pipe_get_config_t ctl_pixtx_pipe_get_config_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_pixtx_pipe_set_config_t -typedef struct _ctl_pixtx_pipe_set_config_t ctl_pixtx_pipe_set_config_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_panel_descriptor_access_args_t -typedef struct _ctl_panel_descriptor_access_args_t ctl_panel_descriptor_access_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_retro_scaling_settings_t -typedef struct _ctl_retro_scaling_settings_t ctl_retro_scaling_settings_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_retro_scaling_caps_t -typedef struct _ctl_retro_scaling_caps_t ctl_retro_scaling_caps_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_scaling_caps_t -typedef struct _ctl_scaling_caps_t ctl_scaling_caps_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_scaling_settings_t -typedef struct _ctl_scaling_settings_t ctl_scaling_settings_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_lace_lux_aggr_map_entry_t -typedef struct _ctl_lace_lux_aggr_map_entry_t ctl_lace_lux_aggr_map_entry_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_lace_lux_aggr_map_t -typedef struct _ctl_lace_lux_aggr_map_t ctl_lace_lux_aggr_map_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_lace_config_t -typedef struct _ctl_lace_config_t ctl_lace_config_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_sw_psr_settings_t -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_intel_arc_sync_profile_params_t -typedef struct _ctl_intel_arc_sync_profile_params_t ctl_intel_arc_sync_profile_params_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_edid_management_args_t -typedef struct _ctl_edid_management_args_t ctl_edid_management_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_get_set_custom_mode_args_t -typedef struct _ctl_get_set_custom_mode_args_t ctl_get_set_custom_mode_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_custom_src_mode_t -typedef struct _ctl_custom_src_mode_t ctl_custom_src_mode_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_child_display_target_mode_t -typedef struct _ctl_child_display_target_mode_t ctl_child_display_target_mode_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_combined_display_child_info_t -typedef struct _ctl_combined_display_child_info_t ctl_combined_display_child_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_combined_display_args_t -typedef struct _ctl_combined_display_args_t ctl_combined_display_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_genlock_display_info_t -typedef struct _ctl_genlock_display_info_t ctl_genlock_display_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_genlock_target_mode_list_t -typedef struct _ctl_genlock_target_mode_list_t ctl_genlock_target_mode_list_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_genlock_topology_t -typedef struct _ctl_genlock_topology_t ctl_genlock_topology_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_genlock_args_t -typedef struct _ctl_genlock_args_t ctl_genlock_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_vblank_ts_args_t -typedef struct _ctl_vblank_ts_args_t ctl_vblank_ts_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_lda_args_t -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; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_engine_stats_t -typedef struct _ctl_engine_stats_t ctl_engine_stats_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_fan_speed_t -typedef struct _ctl_fan_speed_t ctl_fan_speed_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_fan_temp_speed_t -typedef struct _ctl_fan_temp_speed_t ctl_fan_temp_speed_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_fan_speed_table_t -typedef struct _ctl_fan_speed_table_t ctl_fan_speed_table_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_fan_properties_t -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; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_freq_range_t -typedef struct _ctl_freq_range_t ctl_freq_range_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_freq_state_t -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; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_video_processing_super_resolution_t -typedef struct _ctl_video_processing_super_resolution_t ctl_video_processing_super_resolution_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_video_processing_noise_reduction_info_t -typedef struct _ctl_video_processing_noise_reduction_info_t ctl_video_processing_noise_reduction_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_video_processing_noise_reduction_t -typedef struct _ctl_video_processing_noise_reduction_t ctl_video_processing_noise_reduction_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_video_processing_adaptive_contrast_enhancement_info_t -typedef struct _ctl_video_processing_adaptive_contrast_enhancement_info_t ctl_video_processing_adaptive_contrast_enhancement_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_video_processing_adaptive_contrast_enhancement_t -typedef struct _ctl_video_processing_adaptive_contrast_enhancement_t ctl_video_processing_adaptive_contrast_enhancement_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_video_processing_standard_color_correction_info_t -typedef struct _ctl_video_processing_standard_color_correction_info_t ctl_video_processing_standard_color_correction_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_video_processing_standard_color_correction_t -typedef struct _ctl_video_processing_standard_color_correction_t ctl_video_processing_standard_color_correction_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_video_processing_total_color_correction_info_t -typedef struct _ctl_video_processing_total_color_correction_info_t ctl_video_processing_total_color_correction_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_video_processing_total_color_correction_t -typedef struct _ctl_video_processing_total_color_correction_t ctl_video_processing_total_color_correction_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_video_processing_feature_details_t -typedef struct _ctl_video_processing_feature_details_t ctl_video_processing_feature_details_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_video_processing_feature_caps_t -typedef struct _ctl_video_processing_feature_caps_t ctl_video_processing_feature_caps_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_video_processing_feature_getset_t -typedef struct _ctl_video_processing_feature_getset_t ctl_video_processing_feature_getset_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_mem_properties_t -typedef struct _ctl_mem_properties_t ctl_mem_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_mem_state_t -typedef struct _ctl_mem_state_t ctl_mem_state_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_mem_bandwidth_t -typedef struct _ctl_mem_bandwidth_t ctl_mem_bandwidth_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_oc_telemetry_item_t -typedef struct _ctl_oc_telemetry_item_t ctl_oc_telemetry_item_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_oc_control_info_t -typedef struct _ctl_oc_control_info_t ctl_oc_control_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_oc_properties_t -typedef struct _ctl_oc_properties_t ctl_oc_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_oc_vf_pair_t -typedef struct _ctl_oc_vf_pair_t ctl_oc_vf_pair_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_psu_info_t -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; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_pci_speed_t -typedef struct _ctl_pci_speed_t ctl_pci_speed_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_pci_properties_t -typedef struct _ctl_pci_properties_t ctl_pci_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_pci_state_t -typedef struct _ctl_pci_state_t ctl_pci_state_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_power_properties_t -typedef struct _ctl_power_properties_t ctl_power_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_power_energy_counter_t -typedef struct _ctl_power_energy_counter_t ctl_power_energy_counter_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_power_sustained_limit_t -typedef struct _ctl_power_sustained_limit_t ctl_power_sustained_limit_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_power_burst_limit_t -typedef struct _ctl_power_burst_limit_t ctl_power_burst_limit_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_power_peak_limit_t -typedef struct _ctl_power_peak_limit_t ctl_power_peak_limit_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_power_limits_t -typedef struct _ctl_power_limits_t ctl_power_limits_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_energy_threshold_t -typedef struct _ctl_energy_threshold_t ctl_energy_threshold_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Forward-declare ctl_temp_properties_t -typedef struct _ctl_temp_properties_t ctl_temp_properties_t; - - - -#if !defined(__GNUC__) -#pragma endregion // common -#endif -// Intel 'ctlApi' for Device Adapter -#if !defined(__GNUC__) -#pragma region _3D -#endif -/////////////////////////////////////////////////////////////////////////////// -/// @brief Feature type -typedef enum _ctl_3d_feature_t -{ - CTL_3D_FEATURE_FRAME_PACING = 0, ///< Frame pacing. Contains generic enum type fields - CTL_3D_FEATURE_ENDURANCE_GAMING = 1, ///< Endurance gaming. Contains generic integer type fields. Value will be - ///< interpreted as the max FPS to be used when in DC mode globally or per - ///< application - CTL_3D_FEATURE_FRAME_LIMIT = 2, ///< Frame limit for games. Contains generic integer type fields. Value - ///< will be interpreted as the max FPS to be used independent of system - ///< power state - CTL_3D_FEATURE_ANISOTROPIC = 3, ///< ANISOTROPIC. Contains generic enum type fields - CTL_3D_FEATURE_CMAA = 4, ///< CMAA. Contains generic enum type fields - CTL_3D_FEATURE_TEXTURE_FILTERING_QUALITY = 5, ///< Texture filtering quality. Contains generic enum type fields - CTL_3D_FEATURE_ADAPTIVE_TESSELLATION = 6, ///< Adaptive tessellation quality. Contains generic integer type fields - CTL_3D_FEATURE_SHARPENING_FILTER = 7, ///< Sharpening Filter. Contains generic integer type fields - CTL_3D_FEATURE_MSAA = 8, ///< Msaa. Contains generic enum type fields - CTL_3D_FEATURE_GAMING_FLIP_MODES = 9, ///< Various Gaming flip modes like speed frame, smooth sync & force async - ///< flip. Contains generic enum type fields - CTL_3D_FEATURE_ADAPTIVE_SYNC_PLUS = 10, ///< Adaptive sync plus. Refer custom field ::ctl_adaptivesync_caps_t & - ///< ::ctl_adaptivesync_getset_t - CTL_3D_FEATURE_APP_PROFILES = 11, ///< Game Compatibility & Performance Profiles. Refer custom field - ///< ::ctl_3d_app_profiles_caps_t & ::ctl_3d_app_profiles_t - CTL_3D_FEATURE_APP_PROFILE_DETAILS = 12, ///< Game Profile Customization. Refer custom field ::ctl_3d_tier_details_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; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief 3D feature misc flags -typedef uint32_t ctl_3d_feature_misc_flags_t; -typedef enum _ctl_3d_feature_misc_flag_t -{ - 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; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Anisotropic values possible -typedef enum _ctl_3d_anisotropic_types_t -{ - CTL_3D_ANISOTROPIC_TYPES_APP_CHOICE = 0, ///< Application choice - CTL_3D_ANISOTROPIC_TYPES_2X = 2, ///< 2X - CTL_3D_ANISOTROPIC_TYPES_4X = 4, ///< 4X - CTL_3D_ANISOTROPIC_TYPES_8X = 8, ///< 8X - CTL_3D_ANISOTROPIC_TYPES_16X = 16, ///< 16X - CTL_3D_ANISOTROPIC_TYPES_MAX - -} ctl_3d_anisotropic_types_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Texture filtering values possible -typedef enum _ctl_3d_texture_filtering_quality_types_t -{ - CTL_3D_TEXTURE_FILTERING_QUALITY_TYPES_PERFORMANCE = 0, ///< Performance - CTL_3D_TEXTURE_FILTERING_QUALITY_TYPES_BALANCED = 1,///< Balanced - CTL_3D_TEXTURE_FILTERING_QUALITY_TYPES_QUALITY = 2, ///< Quality - CTL_3D_TEXTURE_FILTERING_QUALITY_TYPES_MAX - -} ctl_3d_texture_filtering_quality_types_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Frame pacing values possible -typedef enum _ctl_3d_frame_pacing_types_t -{ - CTL_3D_FRAME_PACING_TYPES_DISABLE = 0, ///< Disable - CTL_3D_FRAME_PACING_TYPES_ENABLE_MODE_FRAME_NO_SMOOTHENING = 1, ///< Enable with scheduler without any frame smoothening - CTL_3D_FRAME_PACING_TYPES_ENABLE_MODE_FRAME_MAX_SMOOTHENING = 2,///< Enable with scheduler with maximum smoothness - CTL_3D_FRAME_PACING_TYPES_ENABLE_MODE_COMPETITIVE_GAMING = 3, ///< Enable with scheduler in competitive gaming mode - CTL_3D_FRAME_PACING_TYPES_MAX - -} ctl_3d_frame_pacing_types_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Endurance Gaming control possible -typedef enum _ctl_3d_endurance_gaming_control_t -{ - CTL_3D_ENDURANCE_GAMING_CONTROL_TURN_OFF = 0, ///< Endurance Gaming disable - CTL_3D_ENDURANCE_GAMING_CONTROL_TURN_ON = 1, ///< Endurance Gaming enable - CTL_3D_ENDURANCE_GAMING_CONTROL_AUTO = 2, ///< Endurance Gaming auto - CTL_3D_ENDURANCE_GAMING_CONTROL_MAX - -} ctl_3d_endurance_gaming_control_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Endurance Gaming modes possible -typedef enum _ctl_3d_endurance_gaming_mode_t -{ - CTL_3D_ENDURANCE_GAMING_MODE_BETTER_PERFORMANCE = 0,///< Endurance Gaming better performance mode - CTL_3D_ENDURANCE_GAMING_MODE_BALANCED = 1, ///< Endurance Gaming balanced mode - CTL_3D_ENDURANCE_GAMING_MODE_MAXIMUM_BATTERY = 2, ///< Endurance Gaming maximum battery mode - CTL_3D_ENDURANCE_GAMING_MODE_MAX - -} 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 -{ - CTL_3D_CMAA_TYPES_TURN_OFF = 0, ///< Turn off - CTL_3D_CMAA_TYPES_OVERRIDE_MSAA = 1, ///< Override MSAA - CTL_3D_CMAA_TYPES_ENHANCE_APPLICATION = 2, ///< Enhance Application - CTL_3D_CMAA_TYPES_MAX - -} ctl_3d_cmaa_types_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Adaptive Tessellation -typedef enum _ctl_3d_adaptive_tessellation_types_t -{ - CTL_3D_ADAPTIVE_TESSELLATION_TYPES_TURN_OFF = 0,///< Turn off - CTL_3D_ADAPTIVE_TESSELLATION_TYPES_TURN_ON = 1, ///< Turn on - CTL_3D_ADAPTIVE_TESSELLATION_TYPES_MAX - -} ctl_3d_adaptive_tessellation_types_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Sharpening filter values possible -typedef enum _ctl_3d_sharpening_filter_types_t -{ - CTL_3D_SHARPENING_FILTER_TYPES_TURN_OFF = 0, ///< Turn off - CTL_3D_SHARPENING_FILTER_TYPES_TURN_ON = 1, ///< Turn on - CTL_3D_SHARPENING_FILTER_TYPES_MAX - -} ctl_3d_sharpening_filter_types_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief MSAA values possible -typedef enum _ctl_3d_msaa_types_t -{ - CTL_3D_MSAA_TYPES_APP_CHOICE = 0, ///< Application choice - CTL_3D_MSAA_TYPES_DISABLED = 1, ///< Disabled. MSAA count 1 - CTL_3D_MSAA_TYPES_2X = 2, ///< 2X - CTL_3D_MSAA_TYPES_4X = 4, ///< 4X - CTL_3D_MSAA_TYPES_8X = 8, ///< 8X - CTL_3D_MSAA_TYPES_16X = 16, ///< 16X - CTL_3D_MSAA_TYPES_MAX - -} ctl_3d_msaa_types_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Gaming flip modes -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 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; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Endurance Gaming caps -typedef struct _ctl_endurance_gaming_caps_t -{ - ctl_property_info_enum_t EGControlCaps; ///< [out] Endurance Gaming control capability - ctl_property_info_enum_t EGModeCaps; ///< [out] Endurance Gaming mode capability - -} ctl_endurance_gaming_caps_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Endurance Gaming Get/Set -typedef struct _ctl_endurance_gaming_t -{ - ctl_3d_endurance_gaming_control_t EGControl; ///< [in,out] Endurance Gaming control - Off/On/Auto - ctl_3d_endurance_gaming_mode_t EGMode; ///< [in,out] Endurance Gaming mode - Better Performance/Balanced/Maximum - ///< Battery - -} ctl_endurance_gaming_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Endurance Gaming version2 Get/Set -typedef struct _ctl_endurance_gaming2_t -{ - ctl_3d_endurance_gaming_control_t EGControl; ///< [in,out] Endurance Gaming control - Off/On/Auto - ctl_3d_endurance_gaming_mode_t EGMode; ///< [in,out] Endurance Gaming mode - Better Performance/Balanced/Maximum - ///< Battery - bool IsFPRequired; ///< [out] Is frame pacing required, dynamic state - double TargetFPS; ///< [out] Target FPS for frame pacing - double RefreshRate; ///< [out] Refresh rate used to calculate target fps - uint32_t Reserved[4]; ///< [out] Reserved fields - -} ctl_endurance_gaming2_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Adaptive sync plus caps -typedef struct _ctl_adaptivesync_caps_t -{ - bool AdaptiveBalanceSupported; ///< [out] Adaptive balance supported - ctl_property_info_float_t AdaptiveBalanceStrengthCaps; ///< [out] Strength of adaptive balance algorithm - min/max/steps/default - -} ctl_adaptivesync_caps_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Adaptive sync plus -typedef struct _ctl_adaptivesync_getset_t -{ - bool AdaptiveSync; ///< [in,out] Adaptive sync. Note that in Windows, OS controls state of - ///< adaptive sync and which game gets the feature using it's own policies - bool AdaptiveBalance; ///< [in,out] Adaptive balance - bool AllowAsyncForHighFPS; ///< [in,out] Allow async flips when FPS is higher than max refresh rate of - ///< the panel - float AdaptiveBalanceStrength; ///< [in,out] Adaptive balance strength - -} ctl_adaptivesync_getset_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Game tier types -typedef uint32_t ctl_3d_tier_type_flags_t; -typedef enum _ctl_3d_tier_type_flag_t -{ - CTL_3D_TIER_TYPE_FLAG_COMPATIBILITY = CTL_BIT(0), ///< Compatibility Tier - CTL_3D_TIER_TYPE_FLAG_PERFORMANCE = CTL_BIT(1), ///< Performance Tier - CTL_3D_TIER_TYPE_FLAG_MAX = 0x80000000 - -} ctl_3d_tier_type_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Game tiers -typedef uint32_t ctl_3d_tier_profile_flags_t; -typedef enum _ctl_3d_tier_profile_flag_t -{ - CTL_3D_TIER_PROFILE_FLAG_TIER_1 = CTL_BIT(0), ///< Tier 1 Profile - CTL_3D_TIER_PROFILE_FLAG_TIER_2 = CTL_BIT(1), ///< Tier 2 Profile - CTL_3D_TIER_PROFILE_FLAG_TIER_RECOMMENDED = CTL_BIT(30),///< Recommended Tier Profile. If set other tier values shouldn't be set - CTL_3D_TIER_PROFILE_FLAG_MAX = 0x80000000 - -} ctl_3d_tier_profile_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Game Profile Capabilities. Typically these remain the same across -/// games. -typedef struct _ctl_3d_app_profiles_caps_t -{ - ctl_3d_tier_type_flags_t SupportedTierTypes; ///< [out] Tier of interest for capability check - uint64_t Reserved; ///< [in,out] Reserved for future - -} ctl_3d_app_profiles_caps_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Game Profile tiers -typedef struct _ctl_3d_app_profiles_t -{ - ctl_3d_tier_type_flag_t TierType; ///< [in] Tier type - ctl_3d_tier_profile_flags_t SupportedTierProfiles; ///< [out] Supported tier profiles bitmask - ctl_3d_tier_profile_flags_t DefaultEnabledTierProfiles; ///< [out] Default tiers which driver will enable if there is no user - ///< specific setting for global or per application - ctl_3d_tier_profile_flags_t CustomizationSupportedTierProfiles; ///< [out] Tiers supporting customization - reserved for future - ctl_3d_tier_profile_flags_t EnabledTierProfiles;///< [in,out] Tier profile(s) to be enabled/disabled in the case of a set - ///< call. For a get call this will return the currently enabled tiers - ctl_3d_tier_profile_flags_t CustomizationEnabledTierProfiles; ///< [in,out] Tier profile(s) which are customized. Caller shall call - ///< ::ctl_3d_tier_details_t to get specifics if any. - uint64_t Reserved; ///< [in,out] Reserved for future - -} ctl_3d_app_profiles_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Game Profile tiers details -typedef struct _ctl_3d_tier_details_t -{ - ctl_3d_tier_type_flag_t TierType; ///< [in] Tier type - ctl_3d_tier_profile_flag_t TierProfile; ///< [in] Tier profile(s) for get/set details - uint64_t Reserved[4]; ///< [in,out] Reserved for future - -} ctl_3d_tier_details_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Emulated Typed 64bit Atomics -typedef enum _ctl_emulated_typed_64bit_atomics_types_t -{ - CTL_EMULATED_TYPED_64BIT_ATOMICS_TYPES_DEFAULT = 0, ///< Default settings is based on workload/driver decision. - CTL_EMULATED_TYPED_64BIT_ATOMICS_TYPES_TURN_ON = 1, ///< Force Turn on - CTL_EMULATED_TYPED_64BIT_ATOMICS_TYPES_TURN_OFF = 2,///< Force Turn off - CTL_EMULATED_TYPED_64BIT_ATOMICS_TYPES_MAX - -} ctl_emulated_typed_64bit_atomics_types_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief VRR windowed BLT control possible. Reserved functionality -typedef enum _ctl_3d_vrr_windowed_blt_reserved_t -{ - CTL_3D_VRR_WINDOWED_BLT_RESERVED_AUTO = 0, ///< VRR windowed BLT auto - CTL_3D_VRR_WINDOWED_BLT_RESERVED_TURN_ON = 1, ///< VRR windowed BLT enable - CTL_3D_VRR_WINDOWED_BLT_RESERVED_TURN_OFF = 2, ///< VRR windowed BLT disable - CTL_3D_VRR_WINDOWED_BLT_RESERVED_MAX - -} ctl_3d_vrr_windowed_blt_reserved_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Global or per app values possible -typedef enum _ctl_3d_global_or_per_app_types_t -{ - CTL_3D_GLOBAL_OR_PER_APP_TYPES_NONE = 0, ///< none - CTL_3D_GLOBAL_OR_PER_APP_TYPES_PER_APP = 1, ///< Opt for per app settings - CTL_3D_GLOBAL_OR_PER_APP_TYPES_GLOBAL = 2, ///< Opt for global settings - CTL_3D_GLOBAL_OR_PER_APP_TYPES_MAX - -} ctl_3d_global_or_per_app_types_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief 3D feature capability details which will have range/supported and -/// default values -typedef struct _ctl_3d_feature_details_t -{ - ctl_3d_feature_t FeatureType; ///< [out] 3D feature type - ctl_property_value_type_t ValueType; ///< [out] Type of value - ctl_property_info_t Value; ///< [out] Union of various type of values for 3D features. For enum types - ///< this can be anisotropic/frame pacing etc. This member is valid iff - ///< ValueType is not CTL_PROPERTY_VALUE_TYPE_CUSTOM - int32_t CustomValueSize; ///< [in] CustomValue buffer size. Typically for a feature requiring custom - ///< struct, caller will know of it upfront and can provide the right size - ///< info here - void* pCustomValue; ///< [in,out] Pointer to a custom structure. Caller should allocate this - ///< buffer with known custom feature structure size. This member is valid - ///< iff ValueType is CTL_PROPERTY_VALUE_TYPE_CUSTOM - bool PerAppSupport; ///< [out] Flag indicating whether the feature is supported per application - ///< or not - int64_t ConflictingFeatures; ///< [out] Mask of ::ctl_3d_feature_t values which can't be enabled along - ///< with the mentioned FeatureType. If this is 0, it meant the feature - ///< doesn't have any conflicts with other features - int16_t FeatureMiscSupport; ///< [out] 3D Feature Miscellaneous support flags. This will be based on - ///< ::ctl_3d_feature_misc_flags_t - int16_t Reserved; ///< [out] Reserved - int16_t Reserved1; ///< [out] Reserved - int16_t Reserved2; ///< [out] Reserved - -} ctl_3d_feature_details_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief 3D feature which are controllable -typedef struct _ctl_3d_feature_caps_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint32_t NumSupportedFeatures; ///< [in,out] Number of elements in supported features array - ctl_3d_feature_details_t* pFeatureDetails; ///< [in,out] Array of feature details - -} ctl_3d_feature_caps_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief 3D feature for get/set -typedef struct _ctl_3d_feature_getset_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_3d_feature_t FeatureType; ///< [in] Features interested in - char* ApplicationName; ///< [in] Application name for which the property type is applicable. If - ///< this is an empty string then this will get/set global settings for the - ///< given adapter. Note that this should contain only the name of the - ///< application and not the system specific path - int8_t ApplicationNameLength; ///< [in] Length of ApplicationName string - bool bSet; ///< [in] Set this if it's a set call - ctl_property_value_type_t ValueType; ///< [in] Type of value. Caller has to ensure it provides the right value - ///< type which decides how one read the union structure below - ctl_property_t Value; ///< [in,out] Union of various type of values for 3D features. For enum - ///< types this can be anisotropic/frame pacing etc. This member is valid - ///< iff ValueType is not CTL_PROPERTY_VALUE_TYPE_CUSTOM - int32_t CustomValueSize; ///< [in] CustomValue buffer size. Typically for a feature requiring custom - ///< struct, caller will know of it upfront and cn provide the right size - ///< info here - void* pCustomValue; ///< [in,out] Pointer to a custom structure. Caller should allocate this - ///< buffer with known custom feature structure size. This member is valid - ///< iff ValueType is CTL_PROPERTY_VALUE_TYPE_CUSTOM - -} ctl_3d_feature_getset_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Load KMD gaming features. Restricted function -typedef struct _ctl_kmd_load_features_t -{ - ctl_application_id_t ReservedFuncID; ///< [in] Unique ID for reserved/special function - bool bLoad; ///< [in] If set, will load known KMD features. If not set will reset known - ///< KMD features to default - int64_t SubsetFeatureMask; ///< [in,out] Mask indicating the subset of KMD features within - ///< ::ctl_3d_feature_t values. Default of 0 indicate all KMD features - char* ApplicationName; ///< [in] Application name for which the KMD properties are loaded for. If - ///< this is an empty string then this will load global settings for the - ///< given adapter. Note that this should contain only the name of the - ///< application and not the system specific path - int8_t ApplicationNameLength; ///< [in] Length of ApplicationName string - int8_t CallerComponent; ///< [in] Caller component - int64_t Reserved[4]; ///< [in] Reserved field - -} ctl_kmd_load_features_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get 3D capabilities -/// -/// @details -/// - The application gets 3D 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_APIEXPORT ctl_result_t CTL_APICALL -ctlGetSupported3DCapabilities( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter - ctl_3d_feature_caps_t* pFeatureCaps ///< [in,out][release] 3D properties - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get/Set 3D feature -/// -/// @details -/// - 3D 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_APIEXPORT ctl_result_t CTL_APICALL -ctlGetSet3DFeature( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter - ctl_3d_feature_getset_t* pFeature ///< [in][release] 3D feature get/set parameter - ); - - -#if !defined(__GNUC__) -#pragma endregion // _3D -#endif -// Intel 'ctlApi' for Device Adapter -#if !defined(__GNUC__) -#pragma region display -#endif -/////////////////////////////////////////////////////////////////////////////// -/// @brief Handle of a display output instance -typedef struct _ctl_display_output_handle_t *ctl_display_output_handle_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Handle of a i2c pin-pair instance -typedef struct _ctl_i2c_pin_pair_handle_t *ctl_i2c_pin_pair_handle_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Check Driver version -/// -/// @details -/// - The application checks driver version -/// -/// @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_APIEXPORT ctl_result_t CTL_APICALL -ctlCheckDriverVersion( - ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter - ctl_version_info_t version_info ///< [in][release] Driver version info - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Enumerate devices -/// -/// @details -/// - The application enumerates all device adapters 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` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlEnumerateDevices( - 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 device instances. If count - ///< is zero, then the api will update the value with the total - ///< number of drivers available. If count is non-zero, then the api will - ///< only retrieve the number of drivers. - ///< If count is larger than the number of drivers available, then the api - ///< will update the value with the correct number of drivers available. - ctl_device_adapter_handle_t* phDevices ///< [in,out][optional][release][range(0, *pCount)] array of driver - ///< instance handles - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Enumerate display outputs -/// -/// @details -/// - Enumerates display output capabilities -/// -/// @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_APIEXPORT ctl_result_t CTL_APICALL -ctlEnumerateDisplayOutputs( - ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to control device adapter - uint32_t* pCount, ///< [in,out][release] pointer to the number of display output instances. - ///< 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 drivers available, then the api - ///< will update the value with the correct number of drivers available. - ctl_display_output_handle_t* phDisplayOutputs ///< [in,out][optional][release][range(0, *pCount)] array of display output - ///< instance handles - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Enumerate I2C Pin Pairs -/// -/// @details -/// - Returns available list of I2C Pin-Pairs on a requested adapter -/// -/// @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_POINTER - "The incoming pointer pCount is null" -/// - ::CTL_RESULT_ERROR_INVALID_SIZE - "The supplied Count is not equal to actual number of i2c pin-pair instances" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlEnumerateI2CPinPairs( - ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] handle to device adapter - uint32_t* pCount, ///< [in,out][release] pointer to the number of i2c pin-pair instances. If - ///< count is zero, then the api will update the value with the total - ///< number of i2c pin-pair instances available. If count is non-zero and - ///< matches the avaialble number of pin-pairs, then the api will only - ///< return the avaialble number of i2c pin-pair instances in phI2cPinPairs. - ctl_i2c_pin_pair_handle_t* phI2cPinPairs ///< [out][optional][release][range(0, *pCount)] array of i2c pin pair - ///< instance handles. Need to be allocated by Caller when supplying the - ///< *pCount > 0. - ///< If Count is not equal to actual number of i2c pin-pair instances, it - ///< will return CTL_RESULT_ERROR_INVALID_SIZE. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief OS specific Display identifiers -typedef union _ctl_os_display_encoder_identifier_t -{ - uint32_t WindowsDisplayEncoderID; ///< [out] Windows OS Display encoder ID - ctl_generic_void_datatype_t DisplayEncoderID; ///< [out] Display encoder ID for non-windows OS - -} ctl_os_display_encoder_identifier_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Various display types -typedef enum _ctl_display_output_types_t -{ - CTL_DISPLAY_OUTPUT_TYPES_INVALID = 0, ///< Invalid - CTL_DISPLAY_OUTPUT_TYPES_DISPLAYPORT = 1, ///< DisplayPort - CTL_DISPLAY_OUTPUT_TYPES_HDMI = 2, ///< HDMI - CTL_DISPLAY_OUTPUT_TYPES_DVI = 3, ///< DVI - CTL_DISPLAY_OUTPUT_TYPES_MIPI = 4, ///< MIPI - CTL_DISPLAY_OUTPUT_TYPES_CRT = 5, ///< CRT - CTL_DISPLAY_OUTPUT_TYPES_MAX - -} ctl_display_output_types_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Supported output bits per color (bpc) bitmasks -typedef uint32_t ctl_output_bpc_flags_t; -typedef enum _ctl_output_bpc_flag_t -{ - CTL_OUTPUT_BPC_FLAG_6BPC = CTL_BIT(0), ///< [out] Is 6bpc supported - CTL_OUTPUT_BPC_FLAG_8BPC = CTL_BIT(1), ///< [out] Is 8bpc supported - CTL_OUTPUT_BPC_FLAG_10BPC = CTL_BIT(2), ///< [out] Is 10bpc supported - CTL_OUTPUT_BPC_FLAG_12BPC = CTL_BIT(3), ///< [out] Is 12bpc supported - CTL_OUTPUT_BPC_FLAG_MAX = 0x80000000 - -} ctl_output_bpc_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Display output features. This will indicate only the high level -/// capabilities -typedef uint32_t ctl_std_display_feature_flags_t; -typedef enum _ctl_std_display_feature_flag_t -{ - CTL_STD_DISPLAY_FEATURE_FLAG_HDCP = CTL_BIT(0), ///< [out] Is HDCP supported - CTL_STD_DISPLAY_FEATURE_FLAG_HD_AUDIO = CTL_BIT(1), ///< [out] Is HD Audio supported - CTL_STD_DISPLAY_FEATURE_FLAG_PSR = CTL_BIT(2), ///< [out] Is VESA PSR supported - CTL_STD_DISPLAY_FEATURE_FLAG_ADAPTIVESYNC_VRR = CTL_BIT(3), ///< [out] Is VESA Adaptive Sync or HDMI VRR supported - 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; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Advanced Graphics Features provided by Intel Graphics Adapter. This -/// will indicate only the high level capabilities -typedef uint32_t ctl_intel_display_feature_flags_t; -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; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Attached Display Mux Type -typedef enum _ctl_attached_display_mux_type_t -{ - CTL_ATTACHED_DISPLAY_MUX_TYPE_NATIVE = 0, ///< [out] Native DP / HDMI - CTL_ATTACHED_DISPLAY_MUX_TYPE_THUNDERBOLT = 1, ///< [out] Thunderbolt - CTL_ATTACHED_DISPLAY_MUX_TYPE_TYPE_C = 2, ///< [out] USB Type C - CTL_ATTACHED_DISPLAY_MUX_TYPE_USB4 = 3, ///< [out] USB4 - CTL_ATTACHED_DISPLAY_MUX_TYPE_MAX - -} ctl_attached_display_mux_type_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Signal Standard -typedef enum _ctl_signal_standard_type_t -{ - CTL_SIGNAL_STANDARD_TYPE_UNKNOWN = 0, ///< [out] Unknown Signal Standard - CTL_SIGNAL_STANDARD_TYPE_CUSTOM = 1, ///< [out] Custom added timing - CTL_SIGNAL_STANDARD_TYPE_DMT = 2, ///< [out] DMT timing - CTL_SIGNAL_STANDARD_TYPE_GTF = 3, ///< [out] GTF Timing - CTL_SIGNAL_STANDARD_TYPE_CVT = 4, ///< [out] CVT Timing - CTL_SIGNAL_STANDARD_TYPE_CTA = 5, ///< [out] CTA Timing - CTL_SIGNAL_STANDARD_TYPE_MAX - -} ctl_signal_standard_type_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Protocol Converter Location -typedef uint32_t ctl_protocol_converter_location_flags_t; -typedef enum _ctl_protocol_converter_location_flag_t -{ - CTL_PROTOCOL_CONVERTER_LOCATION_FLAG_ONBOARD = CTL_BIT(0), ///< [out] OnBoard Protocol Converter - CTL_PROTOCOL_CONVERTER_LOCATION_FLAG_EXTERNAL = CTL_BIT(1), ///< [out] External Dongle - CTL_PROTOCOL_CONVERTER_LOCATION_FLAG_MAX = 0x80000000 - -} ctl_protocol_converter_location_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief [out] Display Output configuration related flags which indicate how -/// the output pixel stream drive the panel -typedef uint32_t ctl_display_config_flags_t; -typedef enum _ctl_display_config_flag_t -{ - CTL_DISPLAY_CONFIG_FLAG_DISPLAY_ACTIVE = CTL_BIT(0),///< [out] DisplayActive 0: InActive 1: Active - CTL_DISPLAY_CONFIG_FLAG_DISPLAY_ATTACHED = CTL_BIT(1), ///< [out] DisplayAttached.This Bit indicates if any dongle/display/hub is - ///< attached to the encoder. 0: Not Attached 1: Attached - CTL_DISPLAY_CONFIG_FLAG_IS_DONGLE_CONNECTED_TO_ENCODER = CTL_BIT(2),///< [out] This BIT will be set if a dongle/hub/onboard protocol converter - ///< , is attached to the encoder - CTL_DISPLAY_CONFIG_FLAG_DITHERING_ENABLED = CTL_BIT(3), ///< [out] This BIT will be set if dithering is enabled on the encoder - CTL_DISPLAY_CONFIG_FLAG_MAX = 0x80000000 - -} ctl_display_config_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief [out] Encoder configuration related flags which indicate how the -/// output pixel stream drive the panel -typedef uint32_t ctl_encoder_config_flags_t; -typedef enum _ctl_encoder_config_flag_t -{ - CTL_ENCODER_CONFIG_FLAG_INTERNAL_DISPLAY = CTL_BIT(0), ///< [out] Internal connection or not - CTL_ENCODER_CONFIG_FLAG_VESA_TILED_DISPLAY = CTL_BIT(1),///< [out] VESA DisplayID based tiled display which is driven by either - ///< multiple physical connections (DisplayPort SST) or virtual streams - ///< (DisplayPort MST) - CTL_ENCODER_CONFIG_FLAG_TYPEC_CAPABLE = CTL_BIT(2), ///< [out] This is set if encoder supports type c display - CTL_ENCODER_CONFIG_FLAG_TBT_CAPABLE = CTL_BIT(3), ///< [out] This is set if encoder supports Thunderbolt display - CTL_ENCODER_CONFIG_FLAG_DITHERING_SUPPORTED = CTL_BIT(4), ///< [out] This BIT will be set if encoder supports dithering - CTL_ENCODER_CONFIG_FLAG_VIRTUAL_DISPLAY = CTL_BIT(5), ///< [out] This BIT will be set if this is a virtual display.Hardware based - ///< features will not be applicable to this display.For collage display - ///< this will be set for the virtual output created by driver. For split - ///< display this will be set for the virtual split displays created out of - ///< one single physical display - CTL_ENCODER_CONFIG_FLAG_HIDDEN_DISPLAY = CTL_BIT(6),///< [out] This BIT will be set if display is hidden from OS - CTL_ENCODER_CONFIG_FLAG_COLLAGE_DISPLAY = CTL_BIT(7), ///< [out] This BIT will be set if this is a collage display - CTL_ENCODER_CONFIG_FLAG_SPLIT_DISPLAY = CTL_BIT(8), ///< [out] This BIT will be set if this is a split display - CTL_ENCODER_CONFIG_FLAG_COMPANION_DISPLAY = CTL_BIT(9), ///< [out] This BIT will be set if this is a companion display - CTL_ENCODER_CONFIG_FLAG_MGPU_COLLAGE_DISPLAY = CTL_BIT(10), ///< [out] This BIT will be set if this is a Multi GPU collage display - CTL_ENCODER_CONFIG_FLAG_MAX = 0x80000000 - -} ctl_encoder_config_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Display Timing -typedef struct _ctl_display_timing_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint64_t PixelClock; ///< [out] Pixel Clock in Hz - uint32_t HActive; ///< [out] Horizontal Active - uint32_t VActive; ///< [out] Vertical Active - uint32_t HTotal; ///< [out] Horizontal Total - uint32_t VTotal; ///< [out] Vertical Total - uint32_t HBlank; ///< [out] Horizontal Blank - uint32_t VBlank; ///< [out] Vertical Blank - uint32_t HSync; ///< [out] Horizontal Blank - uint32_t VSync; ///< [out] Vertical Blank - float RefreshRate; ///< [out] Refresh Rate - ctl_signal_standard_type_t SignalStandard; ///< [out] Signal Standard - uint8_t VicId; ///< [out] VIC ID for CTA timings - -} ctl_display_timing_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief This structure will contain the properties of the display currently -/// attached to the encoder. -typedef struct _ctl_display_properties_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_os_display_encoder_identifier_t Os_display_encoder_handle; ///< [out] OS specific Display ID - ctl_display_output_types_t Type; ///< [out] Device Type from display HW stand point. If a DisplayPort - ///< protocol converter is involved, this will indicate it's DisplayPort. - ///< The protocol converter's output will be available from - ///< ProtocolConverterOutput field - ctl_attached_display_mux_type_t AttachedDisplayMuxType; ///< [out] Attached Display Mux Type - ctl_display_output_types_t ProtocolConverterOutput; ///< [out] Protocol output type which can be used if config flags indicate - ///< it's a protocol converter. If it's not a protocol converter this will - ///< be set to CTL_DISPLAY_OUTPUT_TYPES_INVALID - ctl_revision_datatype_t SupportedSpec; ///< [out] Supported industry spec version. - ctl_output_bpc_flags_t SupportedOutputBPCFlags; ///< [out] Supported output bits per color. Refer ::ctl_output_bpc_flag_t. - ///< This is independent of RGB or YCbCr output.This is the max BPC - ///< supported.BPC will vary per mode based on restrictions like bandwidth - ///< and monitor support - ctl_protocol_converter_location_flags_t ProtocolConverterType; ///< [out] Currently Active Protocol Converter. Refer - ///< ::ctl_protocol_converter_location_flag_t - ctl_display_config_flags_t DisplayConfigFlags; ///< [out] Output configuration related flags which indicate how the output - ///< pixel stream drive the panel. Refer ::ctl_display_config_flag_t - ctl_std_display_feature_flags_t FeatureEnabledFlags;///< [out] Enabled Display features.Refer ::ctl_std_display_feature_flag_t. - ctl_std_display_feature_flags_t FeatureSupportedFlags; ///< [out] Display Supported feature.Refer ::ctl_std_display_feature_flag_t - ctl_intel_display_feature_flags_t AdvancedFeatureEnabledFlags; ///< [out] Enabled advanced feature.Refer - ///< ::ctl_intel_display_feature_flag_t. - ctl_intel_display_feature_flags_t AdvancedFeatureSupportedFlags;///< [out] Supported advanced feature.Refer - ///< ::ctl_intel_display_feature_flag_t. - ctl_display_timing_t Display_Timing_Info; ///< [out] Applied Timing on the Display - uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes - -} ctl_display_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Adapter's display encoder properties -typedef struct _ctl_adapter_display_encoder_properties_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_os_display_encoder_identifier_t Os_display_encoder_handle; ///< [out] OS specific Display ID - ctl_display_output_types_t Type; ///< [out] Device Type from display HW stand point. If a DisplayPort - ///< protocol converter is involved, this will indicate it's DisplayPort. - ///< The protocol converter's output will be available from - ///< ProtocolConverterOutput field - bool IsOnBoardProtocolConverterOutputPresent; ///< [out] Protocol output type which can be used if it's a protocol - ///< converter. If it's not a protocol converter this will be set to - ///< CTL_DISPLAY_OUTPUT_TYPES_INVALID - ctl_revision_datatype_t SupportedSpec; ///< [out] Supported industry spec version - ctl_output_bpc_flags_t SupportedOutputBPCFlags; ///< [out] Supported output bits per color. Refer ::ctl_output_bpc_flag_t. - ///< This is independent of RGB or YCbCr output.This is the max BPC - ///< supported.BPC will vary per mode based on restrictions like bandwidth - ///< and monitor support - ctl_encoder_config_flags_t EncoderConfigFlags; ///< [out] Output configuration related flags which indicate how the output - ///< pixel stream drive the panel. Refer ::ctl_encoder_config_flag_t - ///< Note: - ///< Virtual = 1: This indicates that its a software display. Hardware - ///< based features will not be applicable to this display. - ///< Collage=1,Virtual=1: Indicates the fake display output created by - ///< driver which has the combined resolution of multiple physical displays - ///< involved in collage configuration - ///< Collage=1,Virtual=0: Indicates the child physical displays involved - ///< in a collage configuration. These are real physical outputs - ///< Split=1,Virtual=1 : Indicates the fake display output created by - ///< driver which occupies a portion of a real physical display - ///< Split=1,Virtual=0 : Indicates the physical display which got split - ///< to form multiple split displays - ///< Split=1,Collage=1 : Invalid combination - ///< MgpuCollage=1,Collage=1,Virtual=1: Indicates the fake display - ///< output created by driver which has the combined resolution of multiple - ///< physical displays spread across multiple GPUs involved in Multi-GPU - ///< collage configuration - ///< MgpuCollage=1,Collage=1,Virtual=0: Indicates the child physical - ///< displays involved in a Multi-GPU collage configuration. These are real - ///< physical outputs - ctl_std_display_feature_flags_t FeatureSupportedFlags; ///< [out] Adapter Supported feature flags. Refer - ///< ::ctl_std_display_feature_flag_t - ctl_intel_display_feature_flags_t AdvancedFeatureSupportedFlags;///< [out] Advanced Features Supported by the Adapter. Refer - ///< ::ctl_intel_display_feature_flag_t - uint32_t ReservedFields[16]; ///< [out] Reserved field of 60 bytes - -} ctl_adapter_display_encoder_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Device Properties -/// -/// @details -/// - The application gets device 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 == pProperties` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetDeviceProperties( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to control device adapter - ctl_device_adapter_properties_t* pProperties ///< [in,out][release] Query result for device properties - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Display Properties -/// -/// @details -/// - The application gets display properties -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pProperties` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetDisplayProperties( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_display_properties_t* pProperties ///< [in,out][release] Query result for display properties - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Adapter Display encoder Properties -/// -/// @details -/// - The application gets the graphic adapters display encoder properties -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pProperties` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetAdaperDisplayEncoderProperties( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_adapter_display_encoder_properties_t* pProperties ///< [in,out][release] Query result for adapter display encoder properties - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Level0 Device handle -/// -/// @details -/// - The application gets OneAPI Level0 Device handles -/// -/// @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 == pZeDevice` -/// + `nullptr == hInstance` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetZeDevice( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter - void* pZeDevice, ///< [out][release] ze_device handle - void** hInstance ///< [out][release] Module instance which caller can use to get export - ///< functions directly - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Various sharpness filter types -typedef uint32_t ctl_sharpness_filter_type_flags_t; -typedef enum _ctl_sharpness_filter_type_flag_t -{ - CTL_SHARPNESS_FILTER_TYPE_FLAG_NON_ADAPTIVE = CTL_BIT(0), ///< Non-adaptive sharpness - CTL_SHARPNESS_FILTER_TYPE_FLAG_ADAPTIVE = CTL_BIT(1), ///< Adaptive sharpness - CTL_SHARPNESS_FILTER_TYPE_FLAG_MAX = 0x80000000 - -} ctl_sharpness_filter_type_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Sharpness filter properties -typedef struct _ctl_sharpness_filter_properties_t -{ - ctl_sharpness_filter_type_flags_t FilterType; ///< [out] Filter type. Refer ::ctl_sharpness_filter_type_flag_t - ctl_property_range_info_t FilterDetails; ///< [out] Min, max & step size information - -} ctl_sharpness_filter_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Various sharpness filter types -typedef struct _ctl_sharpness_caps_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_sharpness_filter_type_flags_t SupportedFilterFlags; ///< [out] Supported sharpness filters for a given display output. Refer - ///< ::ctl_sharpness_filter_type_flag_t - uint8_t NumFilterTypes; ///< [out] Number of elements in filter properties array - ctl_sharpness_filter_properties_t* pFilterProperty; ///< [in,out] Array of filter properties structure describing supported - ///< filter capabilities. Caller should provide a pre-allocated memory for - ///< this. - -} ctl_sharpness_caps_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Current sharpness setting -typedef struct _ctl_sharpness_settings_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - bool Enable; ///< [in,out] Current or new state of sharpness setting - ctl_sharpness_filter_type_flags_t FilterType; ///< [in,out] Current or new filter to be set. Refer - ///< ::ctl_sharpness_filter_type_flag_t - float Intensity; ///< [in,out] Setting intensity to be applied - -} ctl_sharpness_settings_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Sharpness capability -/// -/// @details -/// - Returns sharpness capability -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pSharpnessCaps` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetSharpnessCaps( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_sharpness_caps_t* pSharpnessCaps ///< [in,out][release] Query result for sharpness capability - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Sharpness setting -/// -/// @details -/// - Returns current sharpness settings -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pSharpnessSettings` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetCurrentSharpness( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_sharpness_settings_t* pSharpnessSettings ///< [in,out][release] Query result for sharpness current settings - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Set Sharpness setting -/// -/// @details -/// - Set current sharpness settings -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pSharpnessSettings` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlSetCurrentSharpness( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_sharpness_settings_t* pSharpnessSettings ///< [in][release] Set sharpness current settings - ); - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_I2C_MAX_DATA_SIZE -/// @brief I2C Maximum data size -#define CTL_I2C_MAX_DATA_SIZE 0x0080 -#endif // CTL_I2C_MAX_DATA_SIZE - -/////////////////////////////////////////////////////////////////////////////// -/// @brief I2C Access Args input Flags bitmasks -typedef uint32_t ctl_i2c_flags_t; -typedef enum _ctl_i2c_flag_t -{ - CTL_I2C_FLAG_ATOMICI2C = CTL_BIT(0), ///< Force Atomic I2C. - CTL_I2C_FLAG_1BYTE_INDEX = CTL_BIT(1), ///< 1-byte Indexed operation. If no Index Size flag set, decided based on - ///< Offset Value. - CTL_I2C_FLAG_2BYTE_INDEX = CTL_BIT(2), ///< 2-byte Indexed operation. If no Index Size flag set, decided based on - ///< Offset Value. - CTL_I2C_FLAG_4BYTE_INDEX = CTL_BIT(3), ///< 4-byte Indexed operation. If no Index Size flag set, decided based on - ///< Offset Value. - CTL_I2C_FLAG_SPEED_SLOW = CTL_BIT(4), ///< If no Speed Flag is set, defaults to Best Option possible. - 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; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief I2C access arguments -typedef struct _ctl_i2c_access_args_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint32_t DataSize; ///< [in,out] Valid data size - uint32_t Address; ///< [in] Address to read or write - ctl_operation_type_t OpType; ///< [in] Operation type, 1 for Read, 2 for Write, for Write operation, App - ///< needs to run with admin privileges - uint32_t Offset; ///< [in] Offset - ctl_i2c_flags_t Flags; ///< [in] I2C Flags. Refer ::ctl_i2c_flag_t - uint64_t RAD; ///< [in] RAD, For Future use, to be used for branch devices, Interface - ///< will be provided to get RAD - uint8_t Data[CTL_I2C_MAX_DATA_SIZE]; ///< [in,out] Data array - -} ctl_i2c_access_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief I2C Access -/// -/// @details -/// - Interface to access I2C using display handle as identifier. I2C -/// driver override flags are supported only for HDMI displays. -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pI2cAccessArgs` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" -/// - ::CTL_RESULT_ERROR_INVALID_SIZE - "Invalid I2C data size" -/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" -/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -/// - ::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 - "Kernal mode driver call failure" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlI2CAccess( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_i2c_access_args_t* pI2cAccessArgs ///< [in,out] I2c access arguments - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief I2C Access on PinPair Args input Flags bitmasks -typedef uint32_t ctl_i2c_pinpair_flags_t; -typedef enum _ctl_i2c_pinpair_flag_t -{ - CTL_I2C_PINPAIR_FLAG_ATOMICI2C = CTL_BIT(0), ///< Force Atomic I2C. - CTL_I2C_PINPAIR_FLAG_1BYTE_INDEX = CTL_BIT(1), ///< 1-byte Indexed operation. If no Index Size flag set, decided based on - ///< Offset Value. - CTL_I2C_PINPAIR_FLAG_2BYTE_INDEX = CTL_BIT(2), ///< 2-byte Indexed operation. If no Index Size flag set, decided based on - ///< Offset Value. - CTL_I2C_PINPAIR_FLAG_4BYTE_INDEX = CTL_BIT(3), ///< 4-byte Indexed operation. If no Index Size flag set, decided based on - ///< Offset Value. - CTL_I2C_PINPAIR_FLAG_SPEED_SLOW = CTL_BIT(4), ///< If no Speed Flag is set, defaults to Best Option possible. - CTL_I2C_PINPAIR_FLAG_SPEED_FAST = CTL_BIT(5), ///< If no Speed Flag is set, defaults to Best Option possible. - CTL_I2C_PINPAIR_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_PINPAIR_FLAG_MAX = 0x80000000 - -} ctl_i2c_pinpair_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief I2C access on Pin Pair arguments -typedef struct _ctl_i2c_access_pinpair_args_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint32_t DataSize; ///< [in,out] Valid data size - uint32_t Address; ///< [in] Address to read or write - ctl_operation_type_t OpType; ///< [in] Operation type, 1 for Read, 2 for Write, for Write operation, App - ///< needs to run with admin privileges - uint32_t Offset; ///< [in] Offset - ctl_i2c_pinpair_flags_t Flags; ///< [in] I2C Flags. Refer ::ctl_i2c_pinpair_flag_t - uint8_t Data[CTL_I2C_MAX_DATA_SIZE]; ///< [in,out] Data array - uint32_t ReservedFields[4]; ///< [in] Reserved for future use, must be set to Zero. - -} ctl_i2c_access_pinpair_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief I2C Access On Pin Pair -/// -/// @details -/// - Interface to access I2C using pin-pair handle as identifier. -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hI2cPinPair` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pI2cAccessArgs` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" -/// - ::CTL_RESULT_ERROR_INVALID_SIZE - "Invalid I2C data size" -/// - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid Args passed" -/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" -/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -/// - ::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 - "Kernal mode driver call failure" -/// - ::CTL_RESULT_ERROR_INVALID_NULL_HANDLE - "Invalid or Null handle passed" -/// - ::CTL_RESULT_ERROR_EXTERNAL_DISPLAY_ATTACHED - "Write to Address not allowed when Display is connected" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlI2CAccessOnPinPair( - ctl_i2c_pin_pair_handle_t hI2cPinPair, ///< [in] Handle to I2C pin pair. - ctl_i2c_access_pinpair_args_t* pI2cAccessArgs ///< [in,out] I2c access arguments. - ); - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_AUX_MAX_DATA_SIZE -/// @brief Aux Maximum data size -#define CTL_AUX_MAX_DATA_SIZE 132 -#endif // CTL_AUX_MAX_DATA_SIZE - -/////////////////////////////////////////////////////////////////////////////// -/// @brief AUX Flags bitmasks -typedef uint32_t ctl_aux_flags_t; -typedef enum _ctl_aux_flag_t -{ - CTL_AUX_FLAG_NATIVE_AUX = CTL_BIT(0), ///< For Native AUX operation - CTL_AUX_FLAG_I2C_AUX = CTL_BIT(1), ///< For I2C AUX operation - CTL_AUX_FLAG_I2C_AUX_MOT = CTL_BIT(2), ///< For I2C AUX MOT operation - CTL_AUX_FLAG_MAX = 0x80000000 - -} ctl_aux_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief AUX access arguments -typedef struct _ctl_aux_access_args_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_operation_type_t OpType; ///< [in] Operation type, 1 for Read, 2 for Write, for Write operation, App - ///< needs to run with admin privileges - ctl_aux_flags_t Flags; ///< [in] Aux Flags. Refer ::ctl_aux_flag_t - uint32_t Address; ///< [in] Address to read or write - uint64_t RAD; ///< [in] RAD, For Future use, to be used for branch devices, Interface - ///< will be provided to get RAD - uint32_t PortID; ///< [in] Port ID, For Future use, to be used for SST tiled devices - uint32_t DataSize; ///< [in,out] Valid data size - uint8_t Data[CTL_AUX_MAX_DATA_SIZE]; ///< [in,out] Data array - -} ctl_aux_access_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Aux Access -/// -/// @details -/// - The application does Aux access, PSR needs to be disabled for AUX -/// call. -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pAuxAccessArgs` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" -/// - ::CTL_RESULT_ERROR_INVALID_SIZE - "Invalid AUX data size" -/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" -/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -/// - ::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_INVALID_AUX_ACCESS_FLAG - "Invalid flag for AUX access" -/// - ::CTL_RESULT_ERROR_KMD_CALL - "Kernal mode driver call failure" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlAUXAccess( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_aux_access_args_t* pAuxAccessArgs ///< [in,out] Aux access arguments - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Power saving features (Each individual feature's set & get call can be -/// called only once at a time) -typedef uint32_t ctl_power_optimization_flags_t; -typedef enum _ctl_power_optimization_flag_t -{ - CTL_POWER_OPTIMIZATION_FLAG_FBC = CTL_BIT(0), ///< Frame buffer compression - CTL_POWER_OPTIMIZATION_FLAG_PSR = CTL_BIT(1), ///< Panel self refresh - CTL_POWER_OPTIMIZATION_FLAG_DPST = CTL_BIT(2), ///< Display power saving technology (Panel technology dependent) - CTL_POWER_OPTIMIZATION_FLAG_LRR = CTL_BIT(3), ///< Low refresh rate (LRR/ALRR/UBRR), UBRR is supported only for IGCC and - ///< NDA clients. UBZRR and UBLRR both can not be enabled at the same time, - ///< only one can be enabled at a given time - CTL_POWER_OPTIMIZATION_FLAG_LACE = CTL_BIT(4), ///< Lighting Aware Contrast Enhancement - CTL_POWER_OPTIMIZATION_FLAG_MAX = 0x80000000 - -} ctl_power_optimization_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief GPU/Panel/TCON dependent power optimization technology -typedef uint32_t ctl_power_optimization_dpst_flags_t; -typedef enum _ctl_power_optimization_dpst_flag_t -{ - CTL_POWER_OPTIMIZATION_DPST_FLAG_BKLT = CTL_BIT(0), ///< Intel DPST with Backlight control - CTL_POWER_OPTIMIZATION_DPST_FLAG_PANEL_CABC = CTL_BIT(1), ///< Panel TCON specific Content Adaptive Control mechanism - CTL_POWER_OPTIMIZATION_DPST_FLAG_OPST = CTL_BIT(2), ///< Intel OLED Power Saving Technology - CTL_POWER_OPTIMIZATION_DPST_FLAG_ELP = CTL_BIT(3), ///< TCON based Edge Luminance Profile - CTL_POWER_OPTIMIZATION_DPST_FLAG_EPSM = CTL_BIT(4), ///< Extra power saving mode - CTL_POWER_OPTIMIZATION_DPST_FLAG_APD = CTL_BIT(5), ///< Adaptive Pixel Dimming - CTL_POWER_OPTIMIZATION_DPST_FLAG_PIXOPTIX = CTL_BIT(6), ///< TCON+ based DPST like solution - CTL_POWER_OPTIMIZATION_DPST_FLAG_MAX = 0x80000000 - -} ctl_power_optimization_dpst_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Power Source -typedef enum _ctl_power_source_t -{ - CTL_POWER_SOURCE_AC = 0, ///< Power Source AC - CTL_POWER_SOURCE_DC = 1, ///< Power Source DC - CTL_POWER_SOURCE_MAX - -} ctl_power_source_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Power Optimization Plan -typedef enum _ctl_power_optimization_plan_t -{ - CTL_POWER_OPTIMIZATION_PLAN_BALANCED = 0, ///< Balanced mode - CTL_POWER_OPTIMIZATION_PLAN_HIGH_PERFORMANCE = 1, ///< High Performance Mode - CTL_POWER_OPTIMIZATION_PLAN_POWER_SAVER = 2, ///< Power Saver Mode - CTL_POWER_OPTIMIZATION_PLAN_MAX - -} ctl_power_optimization_plan_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Type of low refresh rate feature -typedef uint32_t ctl_power_optimization_lrr_flags_t; -typedef enum _ctl_power_optimization_lrr_flag_t -{ - CTL_POWER_OPTIMIZATION_LRR_FLAG_LRR10 = CTL_BIT(0), ///< LRR 1.0 - CTL_POWER_OPTIMIZATION_LRR_FLAG_LRR20 = CTL_BIT(1), ///< LRR 2.0 - CTL_POWER_OPTIMIZATION_LRR_FLAG_LRR25 = CTL_BIT(2), ///< LRR 2.5 - CTL_POWER_OPTIMIZATION_LRR_FLAG_ALRR = CTL_BIT(3), ///< Autonomous LRR - CTL_POWER_OPTIMIZATION_LRR_FLAG_UBLRR = CTL_BIT(4), ///< User based low refresh rate - CTL_POWER_OPTIMIZATION_LRR_FLAG_UBZRR = CTL_BIT(5), ///< User based zero refresh rate - CTL_POWER_OPTIMIZATION_LRR_FLAG_MAX = 0x80000000 - -} ctl_power_optimization_lrr_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Power optimization caps -typedef struct _ctl_power_optimization_caps_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_power_optimization_flags_t SupportedFeatures; ///< [out] Supported power optimization features. Refer - ///< ::ctl_power_optimization_flag_t - -} ctl_power_optimization_caps_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Power optimization features -/// -/// @details -/// - Returns power optimization capabilities -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pPowerOptimizationCaps` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetPowerOptimizationCaps( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_power_optimization_caps_t* pPowerOptimizationCaps ///< [in,out][release] Query result for power optimization features - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief LRR detailed settings -typedef struct _ctl_power_optimization_lrr_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_power_optimization_lrr_flags_t SupportedLRRTypes; ///< [out] LRR type(s). Refer ::ctl_power_optimization_lrr_flag_t - ctl_power_optimization_lrr_flags_t CurrentLRRTypes; ///< [in,out] Current enabled LRR type(s) or the LRR type(s) to set to. - ///< Refer ::ctl_power_optimization_lrr_flag_t - bool bRequirePSRDisable; ///< [out] Require PSR disable for any change in the selected LRR feature. - ///< Caller can re-enable PSR once the respective LRR feature is - ///< enable/disabled. E.g. for UBRR based on platform this flag may not be - ///< set in which case caller doesn't need to do an explicit PSR disable - uint16_t LowRR; ///< [out] Lowest RR used for LRR functionality if known to source - -} ctl_power_optimization_lrr_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief PSR detailed settings -typedef struct _ctl_power_optimization_psr_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint8_t PSRVersion; ///< [in,out] A value of 1 means PSR1, 2 means PSR2 - bool FullFetchUpdate; ///< [in,out] Full fetch and update - -} ctl_power_optimization_psr_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief DPST detailed settings -typedef struct _ctl_power_optimization_dpst_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint8_t MinLevel; ///< [out] Minimum supported aggressiveness level - uint8_t MaxLevel; ///< [out] Maximum supported aggressiveness level - uint8_t Level; ///< [in,out] Current aggressiveness level to be set - ctl_power_optimization_dpst_flags_t SupportedFeatures; ///< [out] Supported features - ctl_power_optimization_dpst_flags_t EnabledFeatures;///< [in,out] Features enabled or to be enabled. Fill only one feature for - ///< SET call - -} ctl_power_optimization_dpst_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Feature specific power optimization data -typedef union _ctl_power_optimization_feature_specific_info_t -{ - ctl_power_optimization_lrr_t LRRInfo; ///< [out] LRR info - ctl_power_optimization_psr_t PSRInfo; ///< [in,out] PSR info - ctl_power_optimization_dpst_t DPSTInfo; ///< [in,out] DPST info - -} ctl_power_optimization_feature_specific_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Power optimization settings -typedef struct _ctl_power_optimization_settings_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_power_optimization_plan_t PowerOptimizationPlan;///< [in] Power optimization power plan (max power/max perf/balanced) - ctl_power_optimization_flags_t PowerOptimizationFeature;///< [in] Power optimization feature interested in. Refer - ///< ::ctl_power_optimization_flag_t - bool Enable; ///< [in,out] Enable state - ctl_power_optimization_feature_specific_info_t FeatureSpecificData; ///< [in,out] Data specific to the feature caller is interested in - ctl_power_source_t PowerSource; ///< [in] AC/DC - -} ctl_power_optimization_settings_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Brightness settings for SET call -typedef struct _ctl_set_brightness_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint32_t TargetBrightness; ///< [in] The brightness level that the display need to transitioning to in - ///< milli-percentage. Range is 0-100000 (100%) - uint32_t SmoothTransitionTimeInMs; ///< [in] Transition Time for brightness to take effect in milli-seconds. - ///< If its 0 then it will be an immediate change. Maximum possible value - ///< is 1000ms. - uint32_t ReservedFields[4]; ///< [in] Reserved for future use - -} ctl_set_brightness_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Brightness settings for GET call -typedef struct _ctl_get_brightness_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint32_t TargetBrightness; ///< [out] The brightness level that the display is currently transitioning - ///< to in milli-percentage. If not in a transition, this should equal the - ///< current brightness. Range is 0-100000 (100%) - uint32_t CurrentBrightness; ///< [out] The current brightness level of the display in milli-percentage - uint32_t ReservedFields[4]; ///< [out] Reserved for future use - -} ctl_get_brightness_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Power optimization setting -/// -/// @details -/// - Returns power optimization setting for a specific feature -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pPowerOptimizationSettings` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_INVALID_POWERFEATURE_OPTIMIZATION_FLAG - "Unsupported PowerOptimizationFeature" -/// - ::CTL_RESULT_ERROR_INVALID_POWERSOURCE_TYPE_FOR_DPST - "DPST is supported only in DC Mode" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetPowerOptimizationSetting( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_power_optimization_settings_t* pPowerOptimizationSettings ///< [in,out][release] Power optimization data to be fetched - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Set Power optimization setting -/// -/// @details -/// - Set power optimization setting for a specific feature -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pPowerOptimizationSettings` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_INVALID_POWERFEATURE_OPTIMIZATION_FLAG - "Unsupported PowerOptimizationFeature" -/// - ::CTL_RESULT_ERROR_INVALID_POWERSOURCE_TYPE_FOR_DPST - "DPST is supported only in DC Mode" -/// - ::CTL_RESULT_ERROR_SET_FBC_FEATURE_NOT_SUPPORTED - "Set FBC Feature not supported" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlSetPowerOptimizationSetting( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_power_optimization_settings_t* pPowerOptimizationSettings ///< [in][release] Power optimization data to be applied - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Set Brightness on companion display -/// -/// @details -/// - Set Brightness for a target display. Currently support is only for -/// companion display. -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pSetBrightnessSetting` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid Brightness data passed as argument" -/// - ::CTL_RESULT_ERROR_DISPLAY_NOT_ACTIVE - "Display not active" -/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Currently Brightness API is supported only on companion display" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlSetBrightnessSetting( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_set_brightness_t* pSetBrightnessSetting ///< [in][release] Brightness settings to be applied - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Brightness setting -/// -/// @details -/// - Get Brightness for a target display. Currently support is only for -/// companion display. -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pGetBrightnessSetting` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_DISPLAY_NOT_ACTIVE - "Display not active" -/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Currently Brightness API is supported only on companion display" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetBrightnessSetting( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_get_brightness_t* pGetBrightnessSetting ///< [out][release] Brightness settings data to be fetched - ); - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_MAX_NUM_SAMPLES_PER_CHANNEL_1D_LUT -/// @brief Maximum number of samples per channel 1D LUT -#define CTL_MAX_NUM_SAMPLES_PER_CHANNEL_1D_LUT 8192 -#endif // CTL_MAX_NUM_SAMPLES_PER_CHANNEL_1D_LUT - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Pixtx pipe set configuration flags bitmasks -typedef uint32_t ctl_pixtx_pipe_set_config_flags_t; -typedef enum _ctl_pixtx_pipe_set_config_flag_t -{ - CTL_PIXTX_PIPE_SET_CONFIG_FLAG_PERSIST_ACROSS_POWER_EVENTS = CTL_BIT(0),///< For maintaining persistance across power events - CTL_PIXTX_PIPE_SET_CONFIG_FLAG_MAX = 0x80000000 - -} ctl_pixtx_pipe_set_config_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Pixel transformation block types -typedef enum _ctl_pixtx_block_type_t -{ - CTL_PIXTX_BLOCK_TYPE_1D_LUT = 1, ///< Block type 1D LUT - CTL_PIXTX_BLOCK_TYPE_3D_LUT = 2, ///< Block type 3D LUT - CTL_PIXTX_BLOCK_TYPE_3X3_MATRIX = 3, ///< Block type 3x3 matrix - CTL_PIXTX_BLOCK_TYPE_3X3_MATRIX_AND_OFFSETS = 4,///< Block type 3x3 matrix and offsets - CTL_PIXTX_BLOCK_TYPE_MAX - -} ctl_pixtx_block_type_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Pixel transformation LUT sampling types -typedef enum _ctl_pixtx_lut_sampling_type_t -{ - CTL_PIXTX_LUT_SAMPLING_TYPE_UNIFORM = 0, ///< Uniform LUT sampling - CTL_PIXTX_LUT_SAMPLING_TYPE_NONUNIFORM = 1, ///< Non uniform LUT sampling, Required mainly in HDR mode - CTL_PIXTX_LUT_SAMPLING_TYPE_MAX - -} ctl_pixtx_lut_sampling_type_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Configuration query types -typedef enum _ctl_pixtx_config_query_type_t -{ - CTL_PIXTX_CONFIG_QUERY_TYPE_CAPABILITY = 0, ///< Get complete pixel processing pipeline capability - CTL_PIXTX_CONFIG_QUERY_TYPE_CURRENT = 1, ///< Get the configuration set through last set call - CTL_PIXTX_CONFIG_QUERY_TYPE_MAX - -} ctl_pixtx_config_query_type_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Configuration operation types -typedef enum _ctl_pixtx_config_opertaion_type_t -{ - CTL_PIXTX_CONFIG_OPERTAION_TYPE_RESTORE_DEFAULT = 1,///< Restore block by block or entire pipe line. Use NumBlocks = 0 to - ///< restore all. - CTL_PIXTX_CONFIG_OPERTAION_TYPE_SET_CUSTOM = 2, ///< Custom LUT or matrix can be set thorugh this option. - CTL_PIXTX_CONFIG_OPERTAION_TYPE_MAX - -} ctl_pixtx_config_opertaion_type_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Pixel transformation gamma encoding types -typedef enum _ctl_pixtx_gamma_encoding_type_t -{ - CTL_PIXTX_GAMMA_ENCODING_TYPE_SRGB = 0, ///< Gamma encoding SRGB - CTL_PIXTX_GAMMA_ENCODING_TYPE_REC709 = 1, ///< Gamma encoding REC709, Applicable for REC2020 as well - CTL_PIXTX_GAMMA_ENCODING_TYPE_ST2084 = 2, ///< Gamma encoding ST2084 - CTL_PIXTX_GAMMA_ENCODING_TYPE_HLG = 3, ///< Gamma encoding HLG - CTL_PIXTX_GAMMA_ENCODING_TYPE_LINEAR = 4, ///< Gamma encoding linear - CTL_PIXTX_GAMMA_ENCODING_TYPE_MAX - -} ctl_pixtx_gamma_encoding_type_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Pixel transformation color space types -typedef enum _ctl_pixtx_color_space_t -{ - CTL_PIXTX_COLOR_SPACE_REC709 = 0, ///< Color space REC709 - CTL_PIXTX_COLOR_SPACE_REC2020 = 1, ///< Color space REC2020 - CTL_PIXTX_COLOR_SPACE_ADOBE_RGB = 2, ///< Color space AdobeRGB - CTL_PIXTX_COLOR_SPACE_P3_D65 = 3, ///< Color space P3_D65 - CTL_PIXTX_COLOR_SPACE_P3_DCI = 4, ///< Color space P3_DCI - CTL_PIXTX_COLOR_SPACE_P3_D60 = 5, ///< Color space P3_D60 - CTL_PIXTX_COLOR_SPACE_CUSTOM = 0xFFFF, ///< Color space custom, Refer ::ctl_pixtx_color_primaries_t for color - ///< primary details - CTL_PIXTX_COLOR_SPACE_MAX - -} ctl_pixtx_color_space_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Pixel transformation color model types -typedef enum _ctl_pixtx_color_model_t -{ - CTL_PIXTX_COLOR_MODEL_RGB_FR = 0, ///< Color model RGB full range - CTL_PIXTX_COLOR_MODEL_RGB_LR = 1, ///< Color model RGB limited range - CTL_PIXTX_COLOR_MODEL_YCBCR_422_FR = 2, ///< Color model YCBCR 422 full range - CTL_PIXTX_COLOR_MODEL_YCBCR_422_LR = 3, ///< Color model YCBCR 422 limited range - CTL_PIXTX_COLOR_MODEL_YCBCR_420_FR = 4, ///< Color model YCBCR 420 full range - CTL_PIXTX_COLOR_MODEL_YCBCR_420_LR = 5, ///< Color model YCBCR 420 limited range - CTL_PIXTX_COLOR_MODEL_YCBCR_444_FR = 6, ///< Color model YCBCR 444 full range - CTL_PIXTX_COLOR_MODEL_YCBCR_444_LR = 7, ///< Color model YCBCR 444 limited range - CTL_PIXTX_COLOR_MODEL_MAX - -} ctl_pixtx_color_model_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Pixel transformation color primaries -typedef struct _ctl_pixtx_color_primaries_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - double xR; ///< [out] CIE1931 x value with maximum red pixel value - double yR; ///< [out] CIE1931 y value with maximum red pixel value - double xG; ///< [out] CIE1931 x value with maximum green pixel value - double yG; ///< [out] CIE1931 y value with maximum green pixel value - double xB; ///< [out] CIE1931 x value with maximum blue pixel value - double yB; ///< [out] CIE1931 y value with maximum blue pixel value - double xW; ///< [out] CIE1931 x value with maximum white pixel value - double yW; ///< [out] CIE1931 y value with maximum white pixel value - -} ctl_pixtx_color_primaries_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Pixel transformation pixel format -typedef struct _ctl_pixtx_pixel_format_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint32_t BitsPerColor; ///< [out] Bits per color, It Will be 16 for FP16 case - bool IsFloat; ///< [out] Will be set for FP16 or other floating point encoding schemes - ctl_pixtx_gamma_encoding_type_t EncodingType; ///< [out] Encoding type - ctl_pixtx_color_space_t ColorSpace; ///< [out] Color space - ctl_pixtx_color_model_t ColorModel; ///< [out] Color model - ctl_pixtx_color_primaries_t ColorPrimaries; ///< [out] Color primaries, Used mainly for custom color space - double MaxBrightness; ///< [out] Maximum brightness of pixel values. If no input is given, - ///< default will be set to sRGB during set call. If panel capability is - ///< not known get call will default to sRGB. - double MinBrightness; ///< [out] Minimum brightness of pixel values - -} ctl_pixtx_pixel_format_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Pixel transformation 1D LUT configuration -typedef struct _ctl_pixtx_1dlut_config_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_pixtx_lut_sampling_type_t SamplingType; ///< [in,out] Blocks with non-uniform sampling capability support unifrom - ///< sampling also but not vice versa. - uint32_t NumSamplesPerChannel; ///< [in,out] Number of samples per channel. Resampled internally based on - ///< HW capability for uniformly sampled LUT.Maximum supported value is - ///< ::CTL_MAX_NUM_SAMPLES_PER_CHANNEL_1D_LUT Caller needs to use exact - ///< sampling position given in pSamplePositions for non-uniformly sampled - ///< LUTs. - uint32_t NumChannels; ///< [in,out] Number of channels, 1 for Grey scale LUT, 3 for RGB LUT - double* pSampleValues; ///< [in,out] Pointer to sample values, R array followed by G and B arrays - ///< in case of multi-channel LUT. Allocation size for pSampleValues should - ///< be NumSamplesPerChannel * NumChannels * sizeof(double) - double* pSamplePositions; ///< [out] LUT (same for all channels) to represent sampling positions for - ///< non-uniformly sampled LUTs.Can be NULL in case uniformly sampled LUTs - -} ctl_pixtx_1dlut_config_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Pixel transformation matrix configuration -typedef struct _ctl_pixtx_matrix_config_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - double PreOffsets[3]; ///< [in,out] Pre offsets - double PostOffsets[3]; ///< [in,out] Post offsets - double Matrix[3][3]; ///< [in,out] 3x3 Matrix - -} ctl_pixtx_matrix_config_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Pixel transformation 3D LUT sample. Samples are converted to integer -/// based on underlying HW capabilities. Hence slight precision loss will -/// be observed while getting sample values. -typedef struct _ctl_pixtx_3dlut_sample_t -{ - double Red; ///< [in,out] Red output value - double Green; ///< [in,out] Green output value - double Blue; ///< [in,out] Blue output value - -} ctl_pixtx_3dlut_sample_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Pixel transformation 3D LUT configuration -typedef struct _ctl_pixtx_3dlut_config_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint32_t NumSamplesPerChannel; ///< [in,out] Number of samples per channel - ctl_pixtx_3dlut_sample_t* pSampleValues; ///< [in,out] Pointer to sample values, R in outer most loop followed by G - ///< and B - -} ctl_pixtx_3dlut_config_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Pixel transformation configuration -typedef union _ctl_pixtx_config_t -{ - ctl_pixtx_1dlut_config_t OneDLutConfig; ///< [in,out] 1D LUT configuration - ctl_pixtx_3dlut_config_t ThreeDLutConfig; ///< [in,out] 3D LUT configuration - ctl_pixtx_matrix_config_t MatrixConfig; ///< [in,out] Matrix configuration - -} ctl_pixtx_config_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Pixel transformation block configuration -typedef struct _ctl_pixtx_block_config_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint32_t BlockId; ///< [in,out] Unique ID for each pixel processing block. Id for a block is - ///< fixed for a platform. - ctl_pixtx_block_type_t BlockType; ///< [in,out] Block type - ctl_pixtx_config_t Config; ///< [in,out] Configuration - -} ctl_pixtx_block_config_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Pixel transformation pipe get configuration -typedef struct _ctl_pixtx_pipe_get_config_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_pixtx_config_query_type_t QueryType; ///< [in] Query operation type - ctl_pixtx_pixel_format_t InputPixelFormat; ///< [out] Input pixel format - ctl_pixtx_pixel_format_t OutputPixelFormat; ///< [out] Output pixel format - uint32_t NumBlocks; ///< [out] Number of blocks - ctl_pixtx_block_config_t* pBlockConfigs; ///< [out] Pointer to specific configs - -} ctl_pixtx_pipe_get_config_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Pixel transformation pipe set configuration -typedef struct _ctl_pixtx_pipe_set_config_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_pixtx_config_opertaion_type_t OpertaionType;///< [in] Set operation type - ctl_pixtx_pipe_set_config_flags_t Flags; ///< [in] Config flags. Refer ::ctl_pixtx_pipe_set_config_flag_t - uint32_t NumBlocks; ///< [in] Number of blocks - ctl_pixtx_block_config_t* pBlockConfigs; ///< [in,out] Array of block specific configs - -} ctl_pixtx_pipe_set_config_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Pixel transformation get pipe configuration -/// -/// @details -/// - The application does pixel transformation get pipe configuration -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pPixTxGetConfigArgs` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" -/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -/// - ::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 - "Kernal mode driver call failure" -/// - ::CTL_RESULT_ERROR_INVALID_PIXTX_GET_CONFIG_QUERY_TYPE - "Invalid query type" -/// - ::CTL_RESULT_ERROR_INVALID_PIXTX_BLOCK_ID - "Invalid block id" -/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PIXTX_BLOCK_CONFIG_MEMORY - "Insufficient memery allocated for BlockConfigs" -/// - ::CTL_RESULT_ERROR_3DLUT_INVALID_PIPE - "Invalid pipe for 3dlut" -/// - ::CTL_RESULT_ERROR_3DLUT_INVALID_DATA - "Invalid 3dlut data" -/// - ::CTL_RESULT_ERROR_3DLUT_NOT_SUPPORTED_IN_HDR - "3dlut not supported in HDR" -/// - ::CTL_RESULT_ERROR_3DLUT_INVALID_OPERATION - "Invalid 3dlut operation" -/// - ::CTL_RESULT_ERROR_3DLUT_UNSUCCESSFUL - "3dlut call unsuccessful" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlPixelTransformationGetConfig( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_pixtx_pipe_get_config_t* pPixTxGetConfigArgs///< [in,out] Pixel transformation get pipe configiguration arguments - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Pixel transformation set pipe configuration -/// -/// @details -/// - The application does pixel transformation set pipe configuration -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pPixTxSetConfigArgs` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" -/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -/// - ::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 - "Kernal mode driver call failure" -/// - ::CTL_RESULT_ERROR_INVALID_PIXTX_SET_CONFIG_OPERATION_TYPE - "Invalid operation type" -/// - ::CTL_RESULT_ERROR_INVALID_SET_CONFIG_NUMBER_OF_SAMPLES - "Invalid number of samples" -/// - ::CTL_RESULT_ERROR_INVALID_PIXTX_BLOCK_ID - "Invalid block id" -/// - ::CTL_RESULT_ERROR_PERSISTANCE_NOT_SUPPORTED - "Persistance not supported" -/// - ::CTL_RESULT_ERROR_3DLUT_INVALID_PIPE - "Invalid pipe for 3dlut" -/// - ::CTL_RESULT_ERROR_3DLUT_INVALID_DATA - "Invalid 3dlut data" -/// - ::CTL_RESULT_ERROR_3DLUT_NOT_SUPPORTED_IN_HDR - "3dlut not supported in HDR" -/// - ::CTL_RESULT_ERROR_3DLUT_INVALID_OPERATION - "Invalid 3dlut operation" -/// - ::CTL_RESULT_ERROR_3DLUT_UNSUCCESSFUL - "3dlut call unsuccessful" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlPixelTransformationSetConfig( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_pixtx_pipe_set_config_t* pPixTxSetConfigArgs///< [in,out] Pixel transformation set pipe configiguration arguments - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Panel descriptor access arguments -typedef struct _ctl_panel_descriptor_access_args_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_operation_type_t OpType; ///< [in] Operation type, 1 for Read, 2 for Write. App needs to run with - ///< admin privileges for Write operation, Currently only Read operation is - ///< supported - uint32_t BlockNumber; ///< [in] Block number, Need to provide only if acccessing EDID - uint32_t DescriptorDataSize; ///< [in] Descriptor data size, Should be 0 for querying the size and - ///< should be DescriptorDataSize derived from query call otherwise - uint8_t* pDescriptorData; ///< [in,out] Panel descriptor data - -} ctl_panel_descriptor_access_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Panel Descriptor Access -/// -/// @details -/// - The application does EDID or Display ID access -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pPanelDescriptorAccessArgs` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" -/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" -/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -/// - ::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 - "Kernal mode driver call failure" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlPanelDescriptorAccess( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_panel_descriptor_access_args_t* pPanelDescriptorAccessArgs ///< [in,out] Panel descriptor access arguments - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Retro Scaling Types -typedef uint32_t ctl_retro_scaling_type_flags_t; -typedef enum _ctl_retro_scaling_type_flag_t -{ - CTL_RETRO_SCALING_TYPE_FLAG_INTEGER = CTL_BIT(0), ///< Integer Scaling - CTL_RETRO_SCALING_TYPE_FLAG_NEAREST_NEIGHBOUR = CTL_BIT(1), ///< Nearest Neighbour Scaling - CTL_RETRO_SCALING_TYPE_FLAG_MAX = 0x80000000 - -} ctl_retro_scaling_type_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Set/Get Retro Scaling Type -typedef struct _ctl_retro_scaling_settings_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - bool Get; ///< [in][release] Set to true to get current scaling . Set to False to Set - ///< the scaling - bool Enable; ///< [in,out] State of the scaler - ctl_retro_scaling_type_flags_t RetroScalingType;///< [out] Requested retro scaling types. Refer - ///< ::ctl_retro_scaling_type_flag_t - -} ctl_retro_scaling_settings_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Retro Scaling caps -typedef struct _ctl_retro_scaling_caps_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_retro_scaling_type_flags_t SupportedRetroScaling; ///< [out] Supported retro scaling types - -} ctl_retro_scaling_caps_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Supported Retro Scaling Types -/// -/// @details -/// - Returns supported retro scaling capabilities -/// -/// @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 == pRetroScalingCaps` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetSupportedRetroScalingCapability( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to adapter - ctl_retro_scaling_caps_t* pRetroScalingCaps ///< [in,out][release] Query result for supported retro scaling types - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get/Set Retro Scaling -/// -/// @details -/// - Get or Set the status of retro scaling.This Api will do a physical -/// modeset resulting in flash on the screen -/// -/// @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 == pGetSetRetroScalingType` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetSetRetroScaling( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to adapter - ctl_retro_scaling_settings_t* pGetSetRetroScalingType ///< [in,out][release] Get or Set the retro scaling type - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Scaling Types -typedef uint32_t ctl_scaling_type_flags_t; -typedef enum _ctl_scaling_type_flag_t -{ - CTL_SCALING_TYPE_FLAG_IDENTITY = CTL_BIT(0), ///< No scaling is applied and display manages scaling itself when possible - CTL_SCALING_TYPE_FLAG_CENTERED = CTL_BIT(1), ///< Source is not scaled but place in the center of the target display - CTL_SCALING_TYPE_FLAG_STRETCHED = CTL_BIT(2), ///< Source is stretched to fit the target size - CTL_SCALING_TYPE_FLAG_ASPECT_RATIO_CENTERED_MAX = CTL_BIT(3), ///< The aspect ratio is maintained with the source centered - CTL_SCALING_TYPE_FLAG_CUSTOM = CTL_BIT(4), ///< None of the standard types match this .Additional parameters are - ///< required which should be set via a private driver interface - CTL_SCALING_TYPE_FLAG_MAX = 0x80000000 - -} ctl_scaling_type_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Scaling caps -typedef struct _ctl_scaling_caps_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_scaling_type_flags_t SupportedScaling; ///< [out] Supported scaling types. Refer ::ctl_scaling_type_flag_t - -} ctl_scaling_caps_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Set/Get Scaling type -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 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; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Supported Scaling Types -/// -/// @details -/// - Returns supported scaling capabilities -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pScalingCaps` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetSupportedScalingCapability( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_scaling_caps_t* pScalingCaps ///< [in,out][release] Query result for supported scaling types - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Current Scaling -/// -/// @details -/// - Returns current active scaling -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pGetCurrentScalingType` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetCurrentScaling( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_scaling_settings_t* pGetCurrentScalingType ///< [in,out][release] Query result for active scaling types - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Set Scaling Type -/// -/// @details -/// - Returns current active scaling -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pSetScalingType` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlSetCurrentScaling( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_scaling_settings_t* pSetScalingType ///< [in,out][release] Set scaling types - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Ambient light based enhancement table entry -typedef struct _ctl_lace_lux_aggr_map_entry_t -{ - uint32_t Lux; ///< [in,out] Ambient lux - uint8_t AggressivenessPercent; ///< [in,out] Pixel boost agressiveness - -} ctl_lace_lux_aggr_map_entry_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Ambient light based enhancement table -typedef struct _ctl_lace_lux_aggr_map_t -{ - uint32_t MaxNumEntries; ///< [out] Max Number of entries in mapping table supported - uint32_t NumEntries; ///< [in,out] Number of entries in the given mapping table - ctl_lace_lux_aggr_map_entry_t* pLuxToAggrMappingTable; ///< [in] Max number of Entries which can be passed in - ///< LuxToAggrMappingTable - -} ctl_lace_lux_aggr_map_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Data specific to the mode caller is interested in -typedef union _ctl_lace_aggr_config_t -{ - uint8_t FixedAggressivenessLevelPercent; ///< [in,out] Fixed aggressiveness level, applicable for - ///< CTL_LACE_MODE_FIXED_AGGR_LEVEL - ctl_lace_lux_aggr_map_t AggrLevelMap; ///< [in,out] Lux to enhancement mapping table, applicable for - ///< CTL_LACE_MODE_AMBIENT_ADAPTIVE - -} ctl_lace_aggr_config_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Operations used for additional settings -typedef uint32_t ctl_get_operation_flags_t; -typedef enum _ctl_get_operation_flag_t -{ - CTL_GET_OPERATION_FLAG_CURRENT = CTL_BIT(0), ///< Get the details set through last set call - CTL_GET_OPERATION_FLAG_DEFAULT = CTL_BIT(1), ///< Get the driver default values - CTL_GET_OPERATION_FLAG_CAPABILITY = CTL_BIT(2), ///< Get capability - CTL_GET_OPERATION_FLAG_MAX = 0x80000000 - -} ctl_get_operation_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Set Operations used for additional settings -typedef enum _ctl_set_operation_t -{ - CTL_SET_OPERATION_RESTORE_DEFAULT = 0, ///< Restore default values - CTL_SET_OPERATION_CUSTOM = 1, ///< Set custom values - CTL_SET_OPERATION_MAX - -} ctl_set_operation_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Lace Trigger Modes -typedef uint32_t ctl_lace_trigger_flags_t; -typedef enum _ctl_lace_trigger_flag_t -{ - CTL_LACE_TRIGGER_FLAG_AMBIENT_LIGHT = CTL_BIT(0), ///< LACE enhancement depends on Ambient light - CTL_LACE_TRIGGER_FLAG_FIXED_AGGRESSIVENESS = CTL_BIT(1),///< LACE enhancement is as per given fixed aggressiveness level - CTL_LACE_TRIGGER_FLAG_MAX = 0x80000000 - -} ctl_lace_trigger_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Set/Get LACE Config -typedef struct _ctl_lace_config_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - bool Enabled; ///< [in,out] Enable or disable LACE feature - ctl_get_operation_flags_t OpTypeGet; ///< [in] Get Operations used for additional settings - ctl_set_operation_t OpTypeSet; ///< [in] Set Operations used for additional settings - ctl_lace_trigger_flags_t Trigger; ///< [in,out] LACE operating mode to be Triggerd - ctl_lace_aggr_config_t LaceConfig; ///< [in,out] Data specific to the mode, caller is interested in - -} ctl_lace_config_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get LACE Config -/// -/// @details -/// - Returns current LACE Config -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pLaceConfig` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_LACE_INVALID_DATA_ARGUMENT_PASSED - "Lace Incorrrect AggressivePercent data or LuxVsAggressive Map data passed by user" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetLACEConfig( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_lace_config_t* pLaceConfig ///< [out]Lace configuration - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Sets LACE Config -/// -/// @details -/// - Sets LACE Config -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pLaceConfig` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_LACE_INVALID_DATA_ARGUMENT_PASSED - "Lace Incorrrect AggressivePercent data or LuxVsAggressive Map data passed by user" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlSetLACEConfig( - ctl_display_output_handle_t hDisplayOutput, ///< [in]Handle to display output - ctl_lace_config_t* pLaceConfig ///< [in]Lace configuration - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Software PSR status/Set Software PSR settings -typedef struct _ctl_sw_psr_settings_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - bool Set; ///< [in][release] Set to False to Get Software PSR status. Set to True to - ///< Enable/Disable Software PSR - bool Supported; ///< [out] When Get is True, returns if SW PSR is supported - bool Enable; ///< [in,out] When Get is True, returns current state of Software PSR. - ///< When Get is False, Enables/Diasbles Software PSR - -} ctl_sw_psr_settings_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Software PSR caps/Set software PSR State -/// -/// @details -/// - Returns Software PSR status or Sets Software PSR capabilities. This is -/// a reserved capability. By default, software PSR is not supported/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 == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pSoftwarePsrSetting` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlSoftwarePSR( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_sw_psr_settings_t* pSoftwarePsrSetting ///< [in,out][release] Get Software PSR caps/state or Set Software PSR - ///< state - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Intel Arc Sync Monitor Params -typedef struct _ctl_intel_arc_sync_monitor_params_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - bool IsIntelArcSyncSupported; ///< [out] Intel Arc Sync support for the monitor - float MinimumRefreshRateInHz; ///< [out] Minimum Intel Arc Sync refresh rate supported by the monitor - float MaximumRefreshRateInHz; ///< [out] Maximum Intel Arc Sync refresh rate supported by the monitor - uint32_t MaxFrameTimeIncreaseInUs; ///< [out] Max frame time increase in micro seconds from DID2.1 Adaptive - ///< Sync block - uint32_t MaxFrameTimeDecreaseInUs; ///< [out] Max frame time decrease in micro seconds from DID2.1 Adaptive - ///< Sync block - -} ctl_intel_arc_sync_monitor_params_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Intel Arc Sync information for monitor -/// -/// @details -/// - Returns Intel Arc Sync information for selected monitor -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pIntelArcSyncMonitorParams` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetIntelArcSyncInfoForMonitor( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_intel_arc_sync_monitor_params_t* pIntelArcSyncMonitorParams ///< [in,out][release] Intel Arc Sync params for monitor - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Intel Arc Sync profile -typedef enum _ctl_intel_arc_sync_profile_t -{ - CTL_INTEL_ARC_SYNC_PROFILE_INVALID = 0, ///< Invalid profile - CTL_INTEL_ARC_SYNC_PROFILE_RECOMMENDED = 1, ///< Default. Selects appropriate profile based on the monitor. COMPATIBLE - ///< profile is applied if profile is not available for the monitor - CTL_INTEL_ARC_SYNC_PROFILE_EXCELLENT = 2, ///< Unconstrained. Full VRR range of the monitor can be used - CTL_INTEL_ARC_SYNC_PROFILE_GOOD = 3, ///< Some minor range constraints, unlikely to effect user experience but - ///< can reduce flicker on some monitors - CTL_INTEL_ARC_SYNC_PROFILE_COMPATIBLE = 4, ///< Significant constraints that will reduce flicker considerably but are - ///< likely to cause some level of judder onscreen especially when refresh - ///< rates are changing rapidly - CTL_INTEL_ARC_SYNC_PROFILE_OFF = 5, ///< Disable Intel Arc Sync on this monitor. This disables variable rate - ///< flips on this monitor. All sync flips will occur at the OS requested - ///< refresh rate - CTL_INTEL_ARC_SYNC_PROFILE_VESA = 6, ///< Applies vesa specified constraints if the monitor has provided them, - ///< COMPATIBLE profile if not - CTL_INTEL_ARC_SYNC_PROFILE_CUSTOM = 7, ///< Unlocks controls to set a custom Intel Arc Sync profile - CTL_INTEL_ARC_SYNC_PROFILE_MAX - -} ctl_intel_arc_sync_profile_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Intel Arc Sync Profile Params -typedef struct _ctl_intel_arc_sync_profile_params_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_intel_arc_sync_profile_t IntelArcSyncProfile; ///< [in,out] Intel Arc Sync profile used by driver. Refer - ///< ::ctl_intel_arc_sync_profile_t - float MaxRefreshRateInHz; ///< [in,out] Maximum refresh rate utilized by the driver - float MinRefreshRateInHz; ///< [in,out] Minimum refresh rate utilized by the driver - uint32_t MaxFrameTimeIncreaseInUs; ///< [in,out] Maximum frame time increase (in micro seconds) imposed by the - ///< driver - uint32_t MaxFrameTimeDecreaseInUs; ///< [in,out] Maximum frame time decrease (in micro seconds) imposed by the - ///< driver - -} ctl_intel_arc_sync_profile_params_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Intel Arc Sync profile -/// -/// @details -/// - Returns Intel Arc Sync profile for selected monitor -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pIntelArcSyncProfileParams` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetIntelArcSyncProfile( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_intel_arc_sync_profile_params_t* pIntelArcSyncProfileParams ///< [in,out][release] Intel Arc Sync params for monitor - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Set Intel Arc Sync profile -/// -/// @details -/// - Sets Intel Arc Sync profile for selected monitor. In a mux situation, -/// this API should be called for all display IDs associated with a -/// physical display. -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pIntelArcSyncProfileParams` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlSetIntelArcSyncProfile( - ctl_display_output_handle_t hDisplayOutput, ///< [in][release] Handle to display output - ctl_intel_arc_sync_profile_params_t* pIntelArcSyncProfileParams ///< [in][release] Intel Arc Sync params for monitor - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief EDID Management operation type -typedef enum _ctl_edid_management_optype_t -{ - CTL_EDID_MANAGEMENT_OPTYPE_READ_EDID = 1, ///< This operation type is to read an output's EDID. Set edid_type input - ///< arg to read MONITOR EDID or previously OVERRIDDEN EDID or CURRENT - ///< active EDID. Read EDID is a 2 pass call. First call with size = 0, - ///< pEdidBuf = nullptr to get the size, then call with allocated buffer to - ///< get the EDID data. READ operation is applicable for any normal, edid - ///< locked or edid overridden display output device. - CTL_EDID_MANAGEMENT_OPTYPE_LOCK_EDID = 2, ///< To make an output always connected with OVERRIDE or MONITOR EDID - ///< across reboots. When output isn't connected call with OVERRIDE EDID; - ///< when connected, either set OVERRIDE and provide pEdidBuf or set - ///< MONITOR and driver will use monitor's EDID. There is no change to EDID - ///< stored in Monitor. Cannot be called when override is active. Any OS - ///< EDID override will take precedence over IGCL override. - CTL_EDID_MANAGEMENT_OPTYPE_UNLOCK_EDID = 3, ///< To undo lock EDID operation, i.e. it makes output as detached in - ///< response to unplug. This operation removes past supplied EDID; output - ///< status is reported to OS as it is; output restores back to monitor's - ///< EDID when it is connected - CTL_EDID_MANAGEMENT_OPTYPE_OVERRIDE_EDID = 4, ///< To replace an output's EDID with supplied one (pEdidBuf) only when - ///< physical display is connected. There is no change to EDID stored in - ///< Monitor. Cannot apply this operation on locked output. When no output - ///< device attached, the supplied EDID will be persisted in driver for - ///< future use. Any OS EDID override will take precedence over IGCL - ///< override. - CTL_EDID_MANAGEMENT_OPTYPE_UNDO_OVERRIDE_EDID = 5, ///< To undo override EDID operation, that is remove previously overridden - ///< EDID on an output. Output restores back to monitor's EDID when it is - ///< connected - CTL_EDID_MANAGEMENT_OPTYPE_MAX - -} ctl_edid_management_optype_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief EDID type. Used in LOCK_EDID and READ_EDID calls. -typedef enum _ctl_edid_type_t -{ - CTL_EDID_TYPE_CURRENT = 1, ///< [in] Used to return currently active EDID in READ_EDID call. - CTL_EDID_TYPE_OVERRIDE = 2, ///< [in] Is it user supplied EDID. Used in LOCK_EDID call with Supplied - ///< EDID or in READ_EDID to get Supplied EDID. - CTL_EDID_TYPE_MONITOR = 3, ///< [in] Is it Monitor's EDID. Used in LOCK_EDID and READ_EDID calls. - CTL_EDID_TYPE_MAX - -} ctl_edid_type_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Edid management operation Out Flags -typedef uint32_t ctl_edid_management_out_flags_t; -typedef enum _ctl_edid_management_out_flag_t -{ - CTL_EDID_MANAGEMENT_OUT_FLAG_OS_CONN_NOTIFICATION = CTL_BIT(0), ///< [out] If OS was notified about a connection change. App will need to - ///< wait for the OS action to complete. - CTL_EDID_MANAGEMENT_OUT_FLAG_SUPPLIED_EDID = CTL_BIT(1),///< [out] Is it previously supplied EDID, set for READ_EDID(CURRENT). - CTL_EDID_MANAGEMENT_OUT_FLAG_MONITOR_EDID = CTL_BIT(2), ///< [out] Is it Monitor's EDID, set for READ_EDID(CURRENT). - CTL_EDID_MANAGEMENT_OUT_FLAG_DISPLAY_CONNECTED = CTL_BIT(3),///< [out] Is Monitor physically connected - CTL_EDID_MANAGEMENT_OUT_FLAG_MAX = 0x80000000 - -} ctl_edid_management_out_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief EDID management -typedef struct _ctl_edid_management_args_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_edid_management_optype_t OpType; ///< [in] EDID managmeent operation type - ctl_edid_type_t EdidType; ///< [in] EDID Type, Monitor or Supplied - uint32_t EdidSize; ///< [in,out] EDID Size, should be 0 for querying the size of EDID, should - ///< be previously returned size to read EDID. if buffer isn't big enough - ///< to fit EDID, returns size of EDID bytes. - uint8_t* pEdidBuf; ///< [in,out] buffer holding EDID data - ctl_edid_management_out_flags_t OutFlags; ///< [out] Output flags to inform about status of EDID management - ///< operations - -} ctl_edid_management_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief EDID Management allows managing an output's EDID or Plugged Status. -/// -/// @details -/// - To manage output's EDID or Display ID. Supports native DP SST and HDMI -/// Display types. -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pEdidManagementArgs` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" -/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -/// - ::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 - "Kernal mode driver call failure" -/// - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid combination of parameters" -/// - ::CTL_RESULT_ERROR_DISPLAY_NOT_ATTACHED - "Error for Output Device not attached" -/// - ::CTL_RESULT_ERROR_OUT_OF_DEVICE_MEMORY - "Insufficient device memory to satisfy call" -/// - ::CTL_RESULT_ERROR_DATA_NOT_FOUND - "Requested EDID data not present." -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlEdidManagement( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_edid_management_args_t* pEdidManagementArgs ///< [in,out] EDID management arguments - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Custom mode operation types -typedef enum _ctl_custom_mode_operation_types_t -{ - CTL_CUSTOM_MODE_OPERATION_TYPES_GET_CUSTOM_SOURCE_MODES = 0,///< Get details of all previous applied custom modes if any. - CTL_CUSTOM_MODE_OPERATION_TYPES_ADD_CUSTOM_SOURCE_MODE = 1, ///< Add a new mode. Allows only single mode adition at a time. - CTL_CUSTOM_MODE_OPERATION_TYPES_REMOVE_CUSTOM_SOURCE_MODES = 2, ///< Remove previously added custom mode. Allows single or multiple mode - ///< removal at a time. - CTL_CUSTOM_MODE_OPERATION_TYPES_MAX - -} ctl_custom_mode_operation_types_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get/Set Custom Mode -typedef struct _ctl_get_set_custom_mode_args_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_custom_mode_operation_types_t CustomModeOpType; ///< [in] Custom mode operation type - uint32_t NumOfModes; ///< [in,out] Number of Custom Src Modes to be added/removed/Read. - ctl_custom_src_mode_t* pCustomSrcModeList; ///< [in,out] Custom mode source list which holds source modes to be - ///< added/removed/Read. - -} ctl_get_set_custom_mode_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get/Set Custom Mode -typedef struct _ctl_custom_src_mode_t -{ - uint32_t SourceX; ///< [in,out] CustomMode Source X Size - uint32_t SourceY; ///< [in,out] CustomMode Source Y Size - -} ctl_custom_src_mode_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get/Set Custom mode. -/// -/// @details -/// - To get or set custom mode. -/// - Add custom source mode operation supports only single mode additon at -/// a time. -/// - Remove custom source mode operation supports single or multiple mode -/// removal at a time. -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pCustomModeArgs` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" -/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -/// - ::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 - "Kernal mode driver call failure" -/// - ::CTL_RESULT_ERROR_INVALID_ARGUMENT - "Invalid combination of parameters" -/// - ::CTL_RESULT_ERROR_CUSTOM_MODE_STANDARD_CUSTOM_MODE_EXISTS - "Standard custom mode exists" -/// - ::CTL_RESULT_ERROR_CUSTOM_MODE_NON_CUSTOM_MATCHING_MODE_EXISTS - "Non custom matching mode exists" -/// - ::CTL_RESULT_ERROR_CUSTOM_MODE_INSUFFICIENT_MEMORY - "Custom mode insufficent memory" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetSetCustomMode( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_get_set_custom_mode_args_t* pCustomModeArgs ///< [in,out] Custom mode arguments - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Combined Display operation type -typedef enum _ctl_combined_display_optype_t -{ - CTL_COMBINED_DISPLAY_OPTYPE_IS_SUPPORTED_CONFIG = 1,///< To check whether given outputs can form a combined display, no changes - ///< are applied - CTL_COMBINED_DISPLAY_OPTYPE_ENABLE = 2, ///< To setup and enable a combined display - CTL_COMBINED_DISPLAY_OPTYPE_DISABLE = 3, ///< To disable combined display - CTL_COMBINED_DISPLAY_OPTYPE_QUERY_CONFIG = 4, ///< To query combined display configuration - CTL_COMBINED_DISPLAY_OPTYPE_MAX - -} ctl_combined_display_optype_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Combined Display's child display target mode -typedef struct _ctl_child_display_target_mode_t -{ - uint32_t Width; ///< [in,out] Width - uint32_t Height; ///< [in,out] Height - float RefreshRate; ///< [in,out] Refresh Rate - uint32_t ReservedFields[4]; ///< [out] Reserved field of 16 bytes - -} ctl_child_display_target_mode_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Combined Display's child display information -typedef struct _ctl_combined_display_child_info_t -{ - ctl_display_output_handle_t hDisplayOutput; ///< [in,out] Display output handle under combined display configuration - ctl_rect_t FbSrc; ///< [in,out] FrameBuffer source's RECT within Combined Display respective - ctl_rect_t FbPos; ///< [in,out] FrameBuffer target's RECT within output size - ctl_display_orientation_t DisplayOrientation; ///< [in,out] 0/180 Degree Display orientation (rotation) - ctl_child_display_target_mode_t TargetMode; ///< [in,out] Desired target mode (width, height, refresh) - -} ctl_combined_display_child_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Combined Display arguments -typedef struct _ctl_combined_display_args_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_combined_display_optype_t OpType; ///< [in] Combined display operation type - bool IsSupported; ///< [out] Returns yes/no in response to IS_SUPPORTED_CONFIG command - uint8_t NumOutputs; ///< [in,out] Number of outputs part of desired combined display - ///< configuration - uint32_t CombinedDesktopWidth; ///< [in,out] Width of desired combined display configuration - uint32_t CombinedDesktopHeight; ///< [in,out] Height of desired combined display configuration - ctl_combined_display_child_info_t* pChildInfo; ///< [in,out] List of child display information respective to each output. - ///< Up to 16 displays are supported with up to 4 displays per GPU. - ctl_display_output_handle_t hCombinedDisplayOutput; ///< [in,out] Handle to combined display output - -} ctl_combined_display_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get/Set Combined Display -/// -/// @details -/// - To get or set combined display with given Child Targets on a Single -/// GPU or across identical GPUs. Multi-GPU(MGPU) combined display is -/// reserved i.e. it is not public and requires special application GUID. -/// MGPU Combined Display will get activated or deactivated in next boot. -/// MGPU scenario will internally link the associated adapters via Linked -/// Display Adapter Call, with supplied hDeviceAdapter being the LDA -/// Primary. If Genlock and enabled in Driver registry and supported by -/// given Display Config, MGPU Combined Display will enable MGPU Genlock -/// with supplied hDeviceAdapter being the Genlock Primary Adapter and the -/// First Child Display being the Primary Display. -/// -/// @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 == pCombinedDisplayArgs` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_INVALID_OPERATION_TYPE - "Invalid operation type" -/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" -/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -/// - ::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_FEATURE_NOT_SUPPORTED - "Combined Display feature is not supported in this platform" -/// - ::CTL_RESULT_ERROR_ADAPTER_NOT_SUPPORTED_ON_LDA_SECONDARY - "Unsupported (secondary) adapter handle passed" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetSetCombinedDisplay( - ctl_device_adapter_handle_t hDeviceAdapter, ///< [in][release] Handle to control device adapter - ctl_combined_display_args_t* pCombinedDisplayArgs ///< [in,out] Setup and get combined display arguments - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Display Genlock Operations -typedef enum _ctl_genlock_operation_t -{ - CTL_GENLOCK_OPERATION_GET_TIMING_DETAILS = 0, ///< Get details of GENLOCK support and timing information - CTL_GENLOCK_OPERATION_VALIDATE = 1, ///< Driver to verify that the topology is Genlock capable - CTL_GENLOCK_OPERATION_ENABLE = 2, ///< Enable GENLOCK - CTL_GENLOCK_OPERATION_DISABLE = 3, ///< Disable GENLOCK - CTL_GENLOCK_OPERATION_GET_TOPOLOGY = 4, ///< Get details of the current Genlock topology that is applied - CTL_GENLOCK_OPERATION_MAX - -} ctl_genlock_operation_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Display Genlock Info -typedef struct _ctl_genlock_display_info_t -{ - ctl_display_output_handle_t hDisplayOutput; ///< [in,out] Display output handle under Genlock topology - bool IsPrimary; ///< [in,out] Genlock Primary - -} ctl_genlock_display_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Genlock Target Mode List -typedef struct _ctl_genlock_target_mode_list_t -{ - ctl_display_output_handle_t hDisplayOutput; ///< [in] Display output handle for whom target mode list is required - uint32_t NumModes; ///< [in,out] Number of supported Modes that is returned from a driver - ctl_display_timing_t* pTargetModes; ///< [out] Display Genlock operation and information - -} ctl_genlock_target_mode_list_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Genlock Topology -typedef struct _ctl_genlock_topology_t -{ - uint8_t NumGenlockDisplays; ///< [in,out] Number of Genlock displays - bool IsPrimaryGenlockSystem; ///< [in,out] Primary Genlock system - ctl_display_timing_t CommonTargetMode; ///< [in] Common target mode - ctl_genlock_display_info_t* pGenlockDisplayInfo;///< [in,out] List of Genlock display info - ctl_genlock_target_mode_list_t* pGenlockModeList; ///< [out] List of Genlock target modes - -} ctl_genlock_topology_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Display Genlock Arg type -typedef struct _ctl_genlock_args_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_genlock_operation_t Operation; ///< [in] Display Genlock Operation - ctl_genlock_topology_t GenlockTopology; ///< [in,out] Display Genlock array of topology structures - bool IsGenlockEnabled; ///< [out] Whether the feature is currently enabled or not - bool IsGenlockPossible; ///< [out] Indicates if Genlock can be enabled/disabled with the given - ///< topology - -} ctl_genlock_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get/Set Display Genlock -/// -/// @details -/// - To get or set Display Genlock. -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == hDeviceAdapter` -/// + `nullptr == pGenlockArgs` -/// + `nullptr == hFailureDeviceAdapter` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -/// - ::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_INVALID_SIZE - "Invalid topology structure size" -/// - ::CTL_RESULT_ERROR_KMD_CALL - "Kernel mode driver call failure" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetSetDisplayGenlock( - ctl_device_adapter_handle_t* hDeviceAdapter, ///< [in][release] Handle to control device adapter - ctl_genlock_args_t* pGenlockArgs, ///< [in,out] Display Genlock operation and information - uint32_t AdapterCount, ///< [in] Number of device adapters - ctl_device_adapter_handle_t* hFailureDeviceAdapter ///< [out] Handle to address the failure device adapter in an error case - ); - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_MAX_DISPLAYS_FOR_MGPU_COLLAGE -/// @brief Maximum number of displays for Single Large Screen -#define CTL_MAX_DISPLAYS_FOR_MGPU_COLLAGE 16 -#endif // CTL_MAX_DISPLAYS_FOR_MGPU_COLLAGE - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Vblank timestamp arguments -typedef struct _ctl_vblank_ts_args_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint8_t NumOfTargets; ///< [out] Number of child targets - uint64_t VblankTS[CTL_MAX_DISPLAYS_FOR_MGPU_COLLAGE]; ///< [out] List of vblank timestamps in microseconds per child target - -} ctl_vblank_ts_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Vblank Timestamp -/// -/// @details -/// - To get a list of vblank timestamps in microseconds for each child -/// target of a display. -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pVblankTSArgs` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS - "Insufficient permissions" -/// - ::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_APIEXPORT ctl_result_t CTL_APICALL -ctlGetVblankTimestamp( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - ctl_vblank_ts_args_t* pVblankTSArgs ///< [out] Get vblank timestamp arguments - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Link Display Adapters Arguments -typedef struct _ctl_lda_args_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint8_t NumAdapters; ///< [in,out] Numbers of adapters to be linked. Up to 4 adapters are - ///< supported - ctl_device_adapter_handle_t* hLinkedAdapters; ///< [in,out][release] List of Control device adapter handles to be linked, - ///< first one being Primary Adapter - uint64_t Reserved[4]; ///< [out] Reserved fields. Set to zero. - -} ctl_lda_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Link Display Adapters -/// -/// @details -/// - To Link Display Adapters. -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hPrimaryAdapter` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pLdaArgs` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -/// - ::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_ADAPTER_ALREADY_LINKED - "Adapter is already linked" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlLinkDisplayAdapters( - ctl_device_adapter_handle_t hPrimaryAdapter, ///< [in][release] Handle to Primary adapter in LDA chain - ctl_lda_args_t* pLdaArgs ///< [in] Link Display Adapters Arguments - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Unlink Display Adapters -/// -/// @details -/// - To Unlink Display Adapters -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hPrimaryAdapter` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::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_ADAPTER_NOT_SUPPORTED_ON_LDA_SECONDARY - "Unsupported (secondary) adapter handle passed" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlUnlinkDisplayAdapters( - ctl_device_adapter_handle_t hPrimaryAdapter ///< [in][release] Handle to Primary adapter in LDA chain - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get Linked Display Adapters -/// -/// @details -/// - To return list of Linked Display Adapters. -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hPrimaryAdapter` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pLdaArgs` -/// - ::CTL_RESULT_ERROR_UNSUPPORTED_VERSION - "Unsupported version" -/// - ::CTL_RESULT_ERROR_INVALID_NULL_POINTER - "Invalid null pointer" -/// - ::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_ADAPTER_NOT_SUPPORTED_ON_LDA_SECONDARY - "Unsupported (secondary) adapter handle passed" -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlGetLinkedDisplayAdapters( - ctl_device_adapter_handle_t hPrimaryAdapter, ///< [in][release] Handle to Primary adapter in LDA chain - ctl_lda_args_t* pLdaArgs ///< [out] Link Display Adapters Arguments - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get/Set Dynamic Contrast Enhancement arguments -typedef struct _ctl_dce_args_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 - uint32_t TargetBrightnessPercent; ///< [in] Target brightness percent - double PhaseinSpeedMultiplier; ///< [in] Phase-in speed multiplier for brightness to take effect - uint32_t NumBins; ///< [in,out] Number of histogram bins - bool Enable; ///< [in,out] For get calls, this represents current state & for set this - ///< represents future state - bool IsSupported; ///< [out] is DCE feature supported - uint32_t* pHistogram; ///< [out] Bin wise histogram data of size NumBins * sizeof(uint32_t) for - ///< current frame - -} ctl_dce_args_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get/Set Dynamic Contrast Enhancement -/// -/// @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 -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pDceArgs` -/// - ::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 -ctlGetSetDynamicContrastEnhancement( - ctl_display_output_handle_t hDisplayOutput, ///< [in] Handle to display output - 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; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Operation type -typedef enum _ctl_wire_format_operation_type_t -{ - 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_wire_format_operation_type_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_wire_format_color_model_t ColorModel; ///< [in,out] Color model - ctl_output_bpc_flags_t ColorDepth; ///< [in,out] Color Depth - -} ctl_wire_format_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 - 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_get_set_wire_format_config_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get/Set Color Format and Color Depth -/// -/// @details -/// - 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 == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `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 -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 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 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 -/// - 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 == hDisplayOutput` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `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 -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 // display -#endif -// Intel 'ctlApi' for Device Adapter - ECC -#if !defined(__GNUC__) -#pragma region ecc -#endif -/////////////////////////////////////////////////////////////////////////////// -/// @brief ECC properties. -typedef struct _ctl_ecc_properties_t -{ - 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_ecc_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief ECC state. -typedef enum _ctl_ecc_state_t -{ - 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_ecc_state_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 - 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_ecc_state_desc_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @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 - -} ctl_fan_temp_speed_t; - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_FAN_TEMP_SPEED_PAIR_COUNT -/// @brief Maximum number of fan temperature/speed pairs in the fan speed table. -#define CTL_FAN_TEMP_SPEED_PAIR_COUNT 32 -#endif // CTL_FAN_TEMP_SPEED_PAIR_COUNT - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Fan speed table -typedef struct _ctl_fan_speed_table_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - int32_t numPoints; ///< [in,out] The number of valid points in the fan speed table. 0 means - ///< that there is no fan speed table configured. -1 means that a fan speed - ///< table is not supported by the hardware. - ctl_fan_temp_speed_t table[CTL_FAN_TEMP_SPEED_PAIR_COUNT]; ///< [in,out] Array of temperature/fan speed pairs. The table is ordered - ///< based on temperature from lowest to highest. - -} ctl_fan_speed_table_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Fan properties -typedef struct _ctl_fan_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 fan speed assuming the - ///< user has permissions - uint32_t supportedModes; ///< [out] Bitfield of supported fan configuration modes - ///< (1<<::ctl_fan_speed_mode_t) - uint32_t supportedUnits; ///< [out] Bitfield of supported fan speed units - ///< (1<<::ctl_fan_speed_units_t) - int32_t maxRPM; ///< [out] The maximum RPM of the fan. A value of -1 means that this - ///< property is unknown. - int32_t maxPoints; ///< [out] The maximum number of points in the fan temp/speed table. A - ///< value of -1 means that this fan doesn't support providing a temp/speed - ///< table. - -} ctl_fan_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Fan configuration -typedef struct _ctl_fan_config_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_fan_speed_mode_t mode; ///< [in,out] The fan speed mode (fixed, temp-speed table) - ctl_fan_speed_t speedFixed; ///< [in,out] The current fixed fan speed setting - ctl_fan_speed_table_t speedTable; ///< [out] A table containing temperature/speed pairs - -} ctl_fan_config_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get handle of fans -/// -/// @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 -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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get fan 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 == hFan` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pProperties` -CTL_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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. -/// - 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 == hFan` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pConfig` -CTL_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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. -/// - 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 == hFan` -/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS -/// + User does not have permissions to make these modifications. -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlFanSetDefaultMode( - ctl_fan_handle_t hFan ///< [in] Handle for the component. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Configure the fan to rotate at a fixed speed (set mode to -/// ::CTL_FAN_SPEED_MODE_FIXED) -/// -/// @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 == hFan` -/// - 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. -CTL_APIEXPORT 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 - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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. -/// - 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 == hFan` -/// - 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. -CTL_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get current state of a fan - current mode and speed -/// -/// @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 == 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. -CTL_APIEXPORT ctl_result_t CTL_APICALL -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. - ); - - -#if !defined(__GNUC__) -#pragma endregion // fan -#endif -// Intel 'ctlApi' for Device Adapter - Firmware management -#if !defined(__GNUC__) -#pragma region firmware -#endif -/////////////////////////////////////////////////////////////////////////////// -#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_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_firmware_config_flag_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 - 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_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 -/// be above or below the hardware limits - the hardware will clamp -/// appropriately. -typedef struct _ctl_freq_range_t -{ - uint32_t Size; ///< [in] size of this structure - 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 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 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; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Frequency throttle reasons -typedef uint32_t ctl_freq_throttle_reason_flags_t; -typedef enum _ctl_freq_throttle_reason_flag_t -{ - CTL_FREQ_THROTTLE_REASON_FLAG_AVE_PWR_CAP = CTL_BIT(0), ///< frequency throttled due to average power excursion (PL1) - CTL_FREQ_THROTTLE_REASON_FLAG_BURST_PWR_CAP = CTL_BIT(1), ///< frequency throttled due to burst power excursion (PL2) - CTL_FREQ_THROTTLE_REASON_FLAG_CURRENT_LIMIT = CTL_BIT(2), ///< frequency throttled due to current excursion (PL4) - CTL_FREQ_THROTTLE_REASON_FLAG_THERMAL_LIMIT = CTL_BIT(3), ///< frequency throttled due to thermal excursion (T > TjMax) - CTL_FREQ_THROTTLE_REASON_FLAG_PSU_ALERT = CTL_BIT(4), ///< frequency throttled due to power supply assertion - CTL_FREQ_THROTTLE_REASON_FLAG_SW_RANGE = CTL_BIT(5),///< frequency throttled due to software supplied frequency range - CTL_FREQ_THROTTLE_REASON_FLAG_HW_RANGE = CTL_BIT(6),///< frequency throttled due to a sub block that has a lower frequency - ///< range when it receives clocks - CTL_FREQ_THROTTLE_REASON_FLAG_MAX = 0x80000000 - -} ctl_freq_throttle_reason_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Frequency state -typedef struct _ctl_freq_state_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - double currentVoltage; ///< [out] Current voltage in Volts. A negative value indicates that this - ///< property is not known. - double request; ///< [out] The current frequency request in MHz. A negative value indicates - ///< that this property is not known. - double tdp; ///< [out] The maximum frequency in MHz supported under the current TDP - ///< conditions. This fluctuates dynamically based on the power and thermal - ///< limits of the part. A negative value indicates that this property is - ///< not known. - double efficient; ///< [out] The efficient minimum frequency in MHz. A negative value - ///< indicates that this property is not known. - double actual; ///< [out] The resolved frequency in MHz. A negative value indicates that - ///< this property is not known. - ctl_freq_throttle_reason_flags_t throttleReasons; ///< [out] The reasons that the frequency is being limited by the hardware. - ///< Returns 0 (frequency not throttled) or a combination of ::ctl_freq_throttle_reason_flag_t. - -} ctl_freq_state_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Frequency throttle time snapshot -/// -/// @details -/// - Percent time throttled is calculated by taking two snapshots (s1, s2) -/// and using the equation: %throttled = (s2.throttleTime - -/// s1.throttleTime) / (s2.timestamp - s1.timestamp) -typedef struct _ctl_freq_throttle_time_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint64_t throttleTime; ///< [out] The monotonic counter of time in microseconds that the frequency - ///< has been limited by the hardware. - uint64_t timestamp; ///< [out] Microsecond timestamp when throttleTime was captured. - ///< 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_freq_throttle_time_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get handle of frequency domains -/// -/// @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 -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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get frequency properties - available frequencies -/// -/// @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 == hFrequency` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pProperties` -CTL_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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. -/// -/// @returns -/// - CTL_RESULT_SUCCESS -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hFrequency` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pCount` -CTL_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get current frequency limits -/// -/// @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 == hFrequency` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pLimits` -CTL_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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 == hFrequency` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pLimits` -/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS -/// + User does not have permissions to make these modifications. -CTL_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get current frequency state - frequency request, actual frequency, TDP -/// limits -/// -/// @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 == hFrequency` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pState` -CTL_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get frequency throttle time -/// -/// @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 == hFrequency` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pThrottleTime` -CTL_APIEXPORT 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. - ); - - -#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 -#endif -/////////////////////////////////////////////////////////////////////////////// -/// @brief Feature type -typedef enum _ctl_video_processing_feature_t -{ - CTL_VIDEO_PROCESSING_FEATURE_FILM_MODE_DETECTION = 0, ///< Film mode detection. Contains CTL_PROPERTY_VALUE_TYPE_BOOL ValueType. - CTL_VIDEO_PROCESSING_FEATURE_NOISE_REDUCTION = 1, ///< Noise reduction. Contains CTL_PROPERTY_VALUE_TYPE_CUSTOM type field - ///< using struct ::ctl_video_processing_noise_reduction_t. - CTL_VIDEO_PROCESSING_FEATURE_SHARPNESS = 2, ///< Sharpness. Contains CTL_PROPERTY_VALUE_TYPE_UINT32 ValueType. - CTL_VIDEO_PROCESSING_FEATURE_ADAPTIVE_CONTRAST_ENHANCEMENT = 3, ///< Adaptive contrast enhancement. Contains - ///< CTL_PROPERTY_VALUE_TYPE_CUSTOM type field using struct - ///< ::ctl_video_processing_adaptive_contrast_enhancement_t. - CTL_VIDEO_PROCESSING_FEATURE_SUPER_RESOLUTION = 4, ///< Super resolution. Contains CTL_PROPERTY_VALUE_TYPE_CUSTOM ValueType - ///< using ::ctl_video_processing_super_resolution_t. By defaut, Super - ///< resolution is not active, need application to activate it, please - ///< contact Intel for super resolution activation. - CTL_VIDEO_PROCESSING_FEATURE_STANDARD_COLOR_CORRECTION = 5, ///< Standard color correction. Controls Hue, Saturation, Contrast, - ///< Brightness. Contains CTL_PROPERTY_VALUE_TYPE_CUSTOM type field using - ///< struct ::ctl_video_processing_standard_color_correction_t. - CTL_VIDEO_PROCESSING_FEATURE_TOTAL_COLOR_CORRECTION = 6,///< Total color correction. Controls Red, Green, Blue, Yellow, Cyan, - ///< Magenta. Contains CTL_PROPERTY_VALUE_TYPE_CUSTOM type field using - ///< struct ::ctl_video_processing_total_color_correction_t. - CTL_VIDEO_PROCESSING_FEATURE_SKIN_TONE_ENHANCEMENT = 7, ///< Skin tone enhancement. Contains CTL_PROPERTY_VALUE_TYPE_UINT32 - ///< ValueType. - CTL_VIDEO_PROCESSING_FEATURE_MAX - -} ctl_video_processing_feature_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Super resolution values possible -typedef uint32_t ctl_video_processing_super_resolution_flags_t; -typedef enum _ctl_video_processing_super_resolution_flag_t -{ - CTL_VIDEO_PROCESSING_SUPER_RESOLUTION_FLAG_DISABLE = CTL_BIT(0),///< Disable - CTL_VIDEO_PROCESSING_SUPER_RESOLUTION_FLAG_ENABLE_DEFAULT_SCENARIO_MODE = CTL_BIT(1), ///< Enable with default super resolution mode - CTL_VIDEO_PROCESSING_SUPER_RESOLUTION_FLAG_ENABLE_CONFERENCE_SCENARIO_MODE = CTL_BIT(2),///< Super resolution mode targeted at video conference content - CTL_VIDEO_PROCESSING_SUPER_RESOLUTION_FLAG_ENABLE_CAMERA_SCENARIO_MODE = CTL_BIT(3),///< Super resolution mode targeted at camera capture content (e.g. - ///< security camera) - CTL_VIDEO_PROCESSING_SUPER_RESOLUTION_FLAG_MAX = 0x80000000 - -} ctl_video_processing_super_resolution_flag_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Super Resolution feature details structure to be used with -/// SUPER_RESOLUTION -typedef struct _ctl_video_processing_super_resolution_info_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_video_processing_super_resolution_flags_t super_resolution_flag;///< [in,out] SUPER_RESOLUTION flag - ctl_property_info_uint_t super_resolution_range_in_width; ///< [in,out] The range of input width information(min, max, default and - ///< step size)which super resolution is capable of supporting. - ctl_property_info_uint_t super_resolution_range_in_height; ///< [in,out] The range of input height information(min, max, default and - ///< step size)which super resolution is capable of supporting. - uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes - -} ctl_video_processing_super_resolution_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Super Resolution Get/Set structure to be used with SUPER_RESOLUTION -typedef struct _ctl_video_processing_super_resolution_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_video_processing_super_resolution_flags_t super_resolution_flag;///< [in,out] SUPER_RESOLUTION flag - bool super_resolution_max_in_enabled; ///< [in,out] The enabling of maximum input width and height limition. If - ///< enabled, super resolution will always take effect if the input - ///< resolution is smaller than the below specified max resolution; - ///< otherwise, super_resolution_max_in_width and - ///< super_resolution_max_in_height will be ignored - uint32_t super_resolution_max_in_width; ///< [in,out] The maximum input width limition value setting which super - ///< resolution will be allowed to enabled. - uint32_t super_resolution_max_in_height; ///< [in,out] The maximum input height limiation value setting which super - ///< resolution will be allowed to enabled. - bool super_resolution_reboot_reset; ///< [in,out] Resetting of super resolution after rebooting. - uint32_t ReservedFields[15]; ///< [out] Reserved field of 60 bytes - char ReservedBytes[3]; ///< [out] Reserved field of 3 bytes - -} ctl_video_processing_super_resolution_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Noise Reduction feature details structure to be used with -/// NOISE_REDUCTION -typedef struct _ctl_video_processing_noise_reduction_info_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_property_info_uint_t noise_reduction; ///< [in,out] Noise reduction min, max, default and step size information - bool noise_reduction_auto_detect_supported; ///< [in,out] Noise reduction Auto Detect is supported; only valid if - ///< NOISE_REDUCTION is enabled. If enabled, noise reduction level is - ///< automatically determined and set value is not used. - ctl_property_info_boolean_t noise_reduction_auto_detect;///< [in,out] Noise reduction auto detect default information - uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes - -} ctl_video_processing_noise_reduction_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Noise Reduction Get/Set structure to be used with NOISE_REDUCTION -typedef struct _ctl_video_processing_noise_reduction_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_property_uint_t noise_reduction; ///< [in,out] Noise reduction enable and value setting - ctl_property_boolean_t noise_reduction_auto_detect; ///< [in,out] Noise reduction auto detect setting - uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes - -} ctl_video_processing_noise_reduction_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Adaptive Contrast Enhancement feature details structure to be used -/// with ADAPTIVE_CONTRAST_ENHANCEMENT -typedef struct _ctl_video_processing_adaptive_contrast_enhancement_info_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_property_info_uint_t adaptive_contrast_enhancement; ///< [in,out] Adaptive Contrast Enhancement min, max, default and step size - ///< information - bool adaptive_contrast_enhancement_coexistence_supported; ///< [in,out] Adaptive contrast enhancement coexistance is supported; only - ///< valid if ADAPTIVE_CONTRAST_ENHANCEMENT is enabled. If enabled, Video - ///< adaptive contrast ehancement will be allowed to be enabled and coexist - ///< with Display adaptive contrast ehancement feature. - ctl_property_info_boolean_t adaptive_contrast_enhancement_coexistence; ///< [in,out] Adaptive contrast enhancement coexistence default information - uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes - -} ctl_video_processing_adaptive_contrast_enhancement_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Adaptive Contrast Enhancement Get/Set structure to be used with -/// ADAPTIVE_CONTRAST_ENHANCEMENT -typedef struct _ctl_video_processing_adaptive_contrast_enhancement_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_property_uint_t adaptive_contrast_enhancement; ///< [in,out] Adaptive Contrast Enhancement enable and value setting - ctl_property_boolean_t adaptive_contrast_enhancement_coexistence; ///< [in,out] Adaptive contrast enhancement coexistance setting - uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes - -} ctl_video_processing_adaptive_contrast_enhancement_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Standard Color Correction feature details structure to be used with -/// STANDARD_COLOR_CORRECTION -typedef struct _ctl_video_processing_standard_color_correction_info_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - bool standard_color_correction_default_enable; ///< [in,out] STANDARD_COLOR_CORRECTION default enable setting. This - ///< global settings controls all of Hue, Saturation, Contrast, Brightness - ///< enabling. Individual Enable controls shall be ignored. - ctl_property_info_float_t brightness; ///< [in,out] Brightness min, max, default and step size information - ctl_property_info_float_t contrast; ///< [in,out] Contrast min, max, default and step size information - ctl_property_info_float_t hue; ///< [in,out] Hue min, max, default and step size information - ctl_property_info_float_t saturation; ///< [in,out] Saturation min, max, default and step size information - uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes - -} ctl_video_processing_standard_color_correction_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Standard Color Correction Get/Set structure to be used with -/// STANDARD_COLOR_CORRECTION -typedef struct _ctl_video_processing_standard_color_correction_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - bool standard_color_correction_enable; ///< [in,out] STANDARD_COLOR_CORRECTION enable setting. This global - ///< setting controls all of Hue, Saturation, Contrast, Brightness - ///< enabling. - float brightness; ///< [in,out] Brightness value - float contrast; ///< [in,out] Contrast value - float hue; ///< [in,out] Hue value - float saturation; ///< [in,out] Saturation value - uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes - -} ctl_video_processing_standard_color_correction_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Total Color Correction Get/Set structure to be used with -/// TOTAL_COLOR_CORRECTION -typedef struct _ctl_video_processing_total_color_correction_info_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - bool total_color_correction_default_enable; ///< [in,out] TOTAL_COLOR_CORRECTION enable setting. This global setting - ///< controls all of Red, Green, Blue, Yellow, Cyan, Magenta enabling. - ///< Individual Enable controls shall be ignored. - ctl_property_info_uint_t red; ///< [in,out] Red min, max, default and step size information - ctl_property_info_uint_t green; ///< [in,out] Green min, max, default and step size information - ctl_property_info_uint_t blue; ///< [in,out] Blue min, max, default and step size information - ctl_property_info_uint_t yellow; ///< [in,out] Yellow min, max, default and step size information - ctl_property_info_uint_t cyan; ///< [in,out] Cyan min, max, default and step size information - ctl_property_info_uint_t magenta; ///< [in,out] Magenta min, max, default and step size information - uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes - -} ctl_video_processing_total_color_correction_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Total Color Correction Get/Set structure to be used with -/// TOTAL_COLOR_CORRECTION -typedef struct _ctl_video_processing_total_color_correction_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - bool total_color_correction_enable; ///< [in,out] TOTAL_COLOR_CORRECTION enable setting. This global setting - ///< controls all of Red, Green, Blue, Yellow, Cyan, Magenta enabling. - uint32_t red; ///< [in,out] Red value - uint32_t green; ///< [in,out] Green value - uint32_t blue; ///< [in,out] Blue value - uint32_t yellow; ///< [in,out] Yellow value - uint32_t cyan; ///< [in,out] Cyan value - uint32_t magenta; ///< [in,out] Magenta value - uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes - -} ctl_video_processing_total_color_correction_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Video Processing feature details which will have range supported and -/// default values -typedef struct _ctl_video_processing_feature_details_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_video_processing_feature_t FeatureType; ///< [out] Video processing feature type - ctl_property_value_type_t ValueType; ///< [out] Type of value - ctl_property_info_t Value; ///< [out] Union of various type of values for Video Processing features. - ///< For enum types this can be noise reduction, color control etc. This - ///< member is valid iff ValueType is not CTL_PROPERTY_VALUE_TYPE_CUSTOM - int32_t CustomValueSize; ///< [in] CustomValue buffer size - void* pCustomValue; ///< [in,out] Pointer to a custom structure. Features that use CustomType, - ///< after the first query for all of the supported features the user needs - ///< to allocate this buffer and then query again just this specific - ///< feature for the structure to be filled in. Caller should allocate this - ///< buffer with known custom feature structure size. This member is valid - ///< iff ValueType is CTL_PROPERTY_VALUE_TYPE_CUSTOM. - uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes - -} ctl_video_processing_feature_details_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Video Processing features which are controllable -typedef struct _ctl_video_processing_feature_caps_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint32_t NumSupportedFeatures; ///< [in,out] Number of elements in supported features array - ctl_video_processing_feature_details_t* pFeatureDetails;///< [in,out] Array of supported features and their details - uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes - -} ctl_video_processing_feature_caps_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Video Processing feature for get/set -typedef struct _ctl_video_processing_feature_getset_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_video_processing_feature_t FeatureType; ///< [in] Features interested in - char* ApplicationName; ///< [in] Application name for which the property type is applicable. If - ///< this is an empty string then this will get/set global settings for the - ///< given adapter. Note that this should contain only the name of the - ///< application and not the system specific path. [This is not currently - ///< supported and should be an empty string.] - int8_t ApplicationNameLength; ///< [in] Length of ApplicationName string - bool bSet; ///< [in] Set this if it's a set call - ctl_property_value_type_t ValueType; ///< [in] Type of value. Caller has to ensure it provides the right value - ///< type which decides how one read the union structure below - ctl_property_t Value; ///< [in,out] Union of various type of values for Video Processing - ///< features. For enum types this can be noise reduction, color control - ///< etc. This member is valid iff ValueType is not - ///< CTL_PROPERTY_VALUE_TYPE_CUSTOM - int32_t CustomValueSize; ///< [in] CustomValue buffer size. For a feature requiring custom struct, - ///< caller will know of it upfront the struct to use based on the feautre - ///< and can provide the right size info here - void* pCustomValue; ///< [in,out] Pointer to a custom structure. Caller should allocate this - ///< buffer with known custom feature structure size. This member is valid - ///< iff ValueType is CTL_PROPERTY_VALUE_TYPE_CUSTOM - uint32_t ReservedFields[16]; ///< [out] Reserved field of 64 bytes - -} ctl_video_processing_feature_getset_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @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_APIEXPORT 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 - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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_APIEXPORT 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 - ); - - -#if !defined(__GNUC__) -#pragma endregion // media -#endif -// Intel 'ctlApi' for Device Adapter - Memory management -#if !defined(__GNUC__) -#pragma region memory -#endif -/////////////////////////////////////////////////////////////////////////////// -/// @brief Memory module types -typedef enum _ctl_mem_type_t -{ - CTL_MEM_TYPE_HBM = 0, ///< HBM memory - CTL_MEM_TYPE_DDR = 1, ///< DDR memory - CTL_MEM_TYPE_DDR3 = 2, ///< DDR3 memory - CTL_MEM_TYPE_DDR4 = 3, ///< DDR4 memory - CTL_MEM_TYPE_DDR5 = 4, ///< DDR5 memory - CTL_MEM_TYPE_LPDDR = 5, ///< LPDDR memory - CTL_MEM_TYPE_LPDDR3 = 6, ///< LPDDR3 memory - CTL_MEM_TYPE_LPDDR4 = 7, ///< LPDDR4 memory - CTL_MEM_TYPE_LPDDR5 = 8, ///< LPDDR5 memory - CTL_MEM_TYPE_GDDR4 = 9, ///< GDDR4 memory - CTL_MEM_TYPE_GDDR5 = 10, ///< GDDR5 memory - CTL_MEM_TYPE_GDDR5X = 11, ///< GDDR5X memory - CTL_MEM_TYPE_GDDR6 = 12, ///< GDDR6 memory - CTL_MEM_TYPE_GDDR6X = 13, ///< GDDR6X memory - CTL_MEM_TYPE_GDDR7 = 14, ///< GDDR7 memory - CTL_MEM_TYPE_UNKNOWN = 15, ///< UNKNOWN memory - CTL_MEM_TYPE_MAX - -} ctl_mem_type_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Memory module location -typedef enum _ctl_mem_loc_t -{ - CTL_MEM_LOC_SYSTEM = 0, ///< System memory - CTL_MEM_LOC_DEVICE = 1, ///< On board local device memory - CTL_MEM_LOC_MAX - -} ctl_mem_loc_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Memory properties -typedef struct _ctl_mem_properties_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_mem_type_t type; ///< [out] The memory type - ctl_mem_loc_t location; ///< [out] Location of this memory (system, device) - uint64_t physicalSize; ///< [out] Physical memory size in bytes. A value of 0 indicates that this - ///< property is not known. However, a call to ::ctlMemoryGetState() will - ///< correctly return the total size of usable memory. - int32_t busWidth; ///< [out] Width of the memory bus. A value of -1 means that this property - ///< is unknown. - int32_t numChannels; ///< [out] The number of memory channels. A value of -1 means that this - ///< property is unknown. - -} ctl_mem_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Memory state - health, allocated -/// -/// @details -/// - Percent allocation is given by 100 * (size - free / size. -/// - Percent free is given by 100 * free / size. -typedef struct _ctl_mem_state_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint64_t free; ///< [out] The free memory in bytes - uint64_t size; ///< [out] The total allocatable memory in bytes (can be less than - ///< ::ctl_mem_properties_t.physicalSize) - -} ctl_mem_state_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Memory bandwidth -/// -/// @details -/// - Percent bandwidth is calculated by taking two snapshots (s1, s2) and -/// using the equation: %bw = 10^6 * ((s2.readCounter - s1.readCounter) + -/// (s2.writeCounter - s1.writeCounter)) / (s2.maxBandwidth * -/// (s2.timestamp - s1.timestamp)) -typedef struct _ctl_mem_bandwidth_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint64_t maxBandwidth; ///< [out] Current maximum bandwidth in units of bytes/sec - uint64_t timestamp; ///< [out] The timestamp (in microseconds) when these measurements were 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. - uint64_t readCounter; ///< [out] Total bytes read from memory. Supported only for Version > 0 - uint64_t writeCounter; ///< [out] Total bytes written to memory. Supported only for Version > 0 - -} ctl_mem_bandwidth_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @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_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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_APIEXPORT 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. - ); - - -#if !defined(__GNUC__) -#pragma endregion // memory -#endif -// Intel 'ctlApi' for Device Adapter - Overclock -#if !defined(__GNUC__) -#pragma region overclock -#endif -/////////////////////////////////////////////////////////////////////////////// -/// @brief Telemetry Item for each telemetry property -/// -/// @details -/// - If the supported field is true, then the entire structure has valid -/// information. -/// - The ::ctl_data_value_t is of type ::ctl_data_type_t and units -/// ::ctl_units_t -typedef struct _ctl_oc_telemetry_item_t -{ - bool bSupported; ///< [out] Indicates if the value is supported. - ctl_units_t units; ///< [out] Indicates the units of the value. - ctl_data_type_t type; ///< [out] Indicates the data type. - ctl_data_value_t value; ///< [out] The value of type ::ctl_data_type_t and units ::ctl_units_t. - -} ctl_oc_telemetry_item_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Overclocking Control Information -/// -/// @details -/// - Whether the device supports overclocking. -/// - The -/// bSupported/bRelative/bReference/units/min/max/step/default/reference -/// values for the available overclock controls -/// - The idea is to facilitate the way the applications present overclock -/// settings to the user. If bSupported is false, the corresponding -/// overclock control is not supported -/// - The setting units will be an enum that enables the application to know -/// the units for the control setting e.g. MHz. The min and max settings -/// give the limits for the control. -/// - The step setting gives the minimum change in the control value (plus -/// or minus) - if a control is not changed by at least this amount, the -/// hardware may round up or down. -/// - The default values gives the manufacturing setting for the control. -/// Some controls such as frequency offset and voltage offset are -/// relative; in this case, bRelative will be true, otherwise the control -/// settings are absolute values. -/// - For relative controls and if bReference is true, the reference value -/// gives the absolute value at the default setting. -/// - If bReference is false, the absolute value of the default setting is -/// no not known and it is probably better to display the setting to users -/// as percentage offsets. -typedef struct _ctl_oc_control_info_t -{ - bool bSupported; ///< [out] Indicates if the values are known. - bool bRelative; ///< [out] Indicates if the values are meant to be taken as relative values - ///< instead of absolut values. - bool bReference; ///< [out] For relative values, this indicates if a reference is available. - ctl_units_t units; ///< [out] Units for the values. - double min; ///< [out] Minimum Value. - double max; ///< [out] Maximum Value. - double step; ///< [out] Step Value. - double Default; ///< [out] Default Value. - double reference; ///< [out] Reference Value if the bReference is true. - -} ctl_oc_control_info_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Overclock properties -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 ::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 ::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; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Overclock Voltage Frequency Pair -typedef struct _ctl_oc_vf_pair_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - double Voltage; ///< [in,out] Voltage component of the pair in mV. - double Frequency; ///< [in,out] Frequency component of the pair in MHz. - -} ctl_oc_vf_pair_t; - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_PSU_COUNT -/// @brief Maximum number power supply units. -#define CTL_PSU_COUNT 5 -#endif // CTL_PSU_COUNT - -/////////////////////////////////////////////////////////////////////////////// -/// @brief PSU Type. -typedef enum _ctl_psu_type_t -{ - CTL_PSU_TYPE_PSU_NONE = 0, ///< Type of the PSU is unknown. - CTL_PSU_TYPE_PSU_PCIE = 1, ///< Type of the PSU is PCIe - CTL_PSU_TYPE_PSU_6PIN = 2, ///< Type of the PSU is 6 PIN - CTL_PSU_TYPE_PSU_8PIN = 3, ///< Type of the PSU is 8 PIN - CTL_PSU_TYPE_MAX - -} ctl_psu_type_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief PSU Info -typedef struct _ctl_psu_info_t -{ - bool bSupported; ///< [out] Indicates if this PSU entry is supported. - ctl_psu_type_t psuType; ///< [out] Type of the PSU. - ctl_oc_telemetry_item_t energyCounter; ///< [out] Snapshot of the monotonic energy counter maintained by hardware. - ///< It measures the total energy consumed this power source. By taking the - ///< delta between two snapshots and dividing by the delta time in seconds, - ///< an application can compute the average power. - ctl_oc_telemetry_item_t voltage; ///< [out] Instantaneous snapshot of the voltage of this power source. - -} ctl_psu_info_t; - -/////////////////////////////////////////////////////////////////////////////// -#ifndef CTL_FAN_COUNT -/// @brief Maximum number of Fans -#define CTL_FAN_COUNT 5 -#endif // CTL_FAN_COUNT - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Power Telemetry -typedef struct _ctl_power_telemetry_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_oc_telemetry_item_t timeStamp; ///< [out] Snapshot of the timestamp counter that measures the total time - ///< since Jan 1, 1970 UTC. It is a decimal value in seconds with a minimum - ///< accuracy of 1 millisecond. - ctl_oc_telemetry_item_t gpuEnergyCounter; ///< [out] Snapshot of the monotonic energy counter maintained by hardware. - ///< It measures the total energy consumed by the GPU chip. By taking the - ///< delta between two snapshots and dividing by the delta time in seconds, - ///< an application can compute the average power. - ctl_oc_telemetry_item_t gpuVoltage; ///< [out] Instantaneous snapshot of the voltage feeding the GPU chip. It - ///< is measured at the power supply output - chip input will be lower. - ctl_oc_telemetry_item_t gpuCurrentClockFrequency; ///< [out] Instantaneous snapshot of the GPU chip frequency. - ctl_oc_telemetry_item_t gpuCurrentTemperature; ///< [out] Instantaneous snapshot of the GPU chip temperature, read from - ///< the sensor reporting the highest value. - ctl_oc_telemetry_item_t globalActivityCounter; ///< [out] Snapshot of the monotonic global activity counter. It measures - ///< the time in seconds (accurate down to 1 millisecond) that any GPU - ///< engine is busy. By taking the delta between two snapshots and dividing - ///< by the delta time in seconds, an application can compute the average - ///< percentage utilization of the GPU.. - ctl_oc_telemetry_item_t renderComputeActivityCounter; ///< [out] Snapshot of the monotonic 3D/compute activity counter. It - ///< measures the time in seconds (accurate down to 1 millisecond) that any - ///< 3D render/compute engine is busy. By taking the delta between two - ///< snapshots and dividing by the delta time in seconds, an application - ///< can compute the average percentage utilization of all 3D - ///< render/compute blocks in the GPU. - ctl_oc_telemetry_item_t mediaActivityCounter; ///< [out] Snapshot of the monotonic media activity counter. It measures - ///< the time in seconds (accurate down to 1 millisecond) that any media - ///< engine is busy. By taking the delta between two snapshots and dividing - ///< by the delta time in seconds, an application can compute the average - ///< 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 ::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 - ///< ::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 ::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. - ///< It measures the total energy consumed by the local memory modules. By - ///< taking the delta between two snapshots and dividing by the delta time - ///< in seconds, an application can compute the average power. - ctl_oc_telemetry_item_t vramVoltage; ///< [out] Instantaneous snapshot of the voltage feeding the memory - ///< modules. - ctl_oc_telemetry_item_t vramCurrentClockFrequency; ///< [out] Instantaneous snapshot of the raw clock frequency driving the - ///< memory modules. - ctl_oc_telemetry_item_t vramCurrentEffectiveFrequency; ///< [out] Instantaneous snapshot of the effective data transfer rate that - ///< the memory modules can sustain based on the current clock frequency.. - ctl_oc_telemetry_item_t vramReadBandwidthCounter; ///< [out] Instantaneous snapshot of the monotonic counter that measures - ///< the read traffic from the memory modules. By taking the delta between - ///< two snapshots and dividing by the delta time in seconds, an - ///< application can compute the average read bandwidth. - ctl_oc_telemetry_item_t vramWriteBandwidthCounter; ///< [out] Instantaneous snapshot of the monotonic counter that measures - ///< 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 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; - -/////////////////////////////////////////////////////////////////////////////// -/// @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_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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_APIEXPORT ctl_result_t CTL_APICALL -ctlOverclockWaiverSet( - ctl_device_adapter_handle_t hDeviceHandle ///< [in][release] Handle to display adapter - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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_APIEXPORT 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. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @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 ocMaxVoltageOffset ///< [in] The Overclocking Maximum Voltage Desired in units given in - ///< ::ctl_oc_properties_t::gpuVoltageOffset::units returned from - ///< ::ctlOverclockGetProperties() - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get the current Overclock Vram Memory Speed -/// -/// @details -/// - 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 -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDeviceHandle` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pOcVramMemSpeedLimit` -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlOverclockVramMemSpeedLimitGetV2( - ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - 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 desired Overclock Vram Memory Speed -/// -/// @details -/// - 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 -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDeviceHandle` -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlOverclockVramMemSpeedLimitSetV2( - ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double ocVramMemSpeedLimit ///< [in] The desired Memory Speed in units given in - ///< ::ctl_oc_properties_t::vramMemSpeedLimit::units returned from - ///< ::ctlOverclockGetProperties() - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get the Current Sustained power limit -/// -/// @details -/// - The purpose of this function is to read the current sustained power -/// limit. -/// - 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 -/// - 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 -ctlOverclockPowerLimitGetV2( - ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - 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 -/// -/// @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 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 -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDeviceHandle` -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlOverclockPowerLimitSetV2( - ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - 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 -/// -/// @details -/// - 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 -/// - 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 -ctlOverclockTemperatureLimitGetV2( - ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - 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 -/// -/// @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 -/// - CTL_RESULT_ERROR_UNINITIALIZED -/// - CTL_RESULT_ERROR_DEVICE_LOST -/// - CTL_RESULT_ERROR_INVALID_NULL_HANDLE -/// + `nullptr == hDeviceHandle` -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlOverclockTemperatureLimitSetV2( - ctl_device_adapter_handle_t hDeviceHandle, ///< [in][release] Handle to display adapter - double temperatureLimit ///< [in] The desired temperature limit in Units given in - ///< ::ctl_oc_properties_t::temperatureLimit::units returned from - ///< ::ctlOverclockGetProperties() - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Read VF Curve -/// -/// @details -/// - 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 == 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 -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 Write Custom VF curve -/// -/// @details -/// - 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 == hDeviceAdapter` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pCustomVFCurveTable` -/// - CTL_RESULT_ERROR_UNKNOWN - "Unknown Error" -CTL_APIEXPORT ctl_result_t CTL_APICALL -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 - ); - - -#if !defined(__GNUC__) -#pragma endregion // overclock -#endif -// Intel 'ctlApi' for Device Adapter - PCI Information -#if !defined(__GNUC__) -#pragma region pci -#endif -/////////////////////////////////////////////////////////////////////////////// -/// @brief PCI address -typedef struct _ctl_pci_address_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint32_t domain; ///< [out] BDF domain - uint32_t bus; ///< [out] BDF bus - uint32_t device; ///< [out] BDF device - uint32_t function; ///< [out] BDF function - -} ctl_pci_address_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief PCI speed -typedef struct _ctl_pci_speed_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - int32_t gen; ///< [out] The link generation. A value of -1 means that this property is - ///< unknown. - int32_t width; ///< [out] The number of lanes. A value of -1 means that this property is - ///< unknown. - int64_t maxBandwidth; ///< [out] The maximum bandwidth in bytes/sec (sum of all lanes). A value - ///< of -1 means that this property is unknown. - -} ctl_pci_speed_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Static PCI properties -typedef struct _ctl_pci_properties_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_pci_address_t address; ///< [out] The BDF address - ctl_pci_speed_t maxSpeed; ///< [out] Fastest port configuration supported by the device (sum of all - ///< lanes) - bool resizable_bar_supported; ///< [out] Support for Resizable Bar on this device. - bool resizable_bar_enabled; ///< [out] Resizable Bar enabled on this device - -} ctl_pci_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Dynamic PCI state -typedef struct _ctl_pci_state_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_pci_speed_t speed; ///< [out] The current port configure speed - -} ctl_pci_state_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get PCI properties - address, max speed -/// -/// @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 -ctlPciGetProperties( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter - ctl_pci_properties_t* pProperties ///< [in,out] Will contain the PCI properties. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get current PCI state - current speed -/// -/// @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_APIEXPORT ctl_result_t CTL_APICALL -ctlPciGetState( - ctl_device_adapter_handle_t hDAhandle, ///< [in][release] Handle to display adapter - ctl_pci_state_t* pState ///< [in,out] Will contain the PCI properties. - ); - - -#if !defined(__GNUC__) -#pragma endregion // pci -#endif -// Intel 'ctlApi' for Device Adapter - Power management -#if !defined(__GNUC__) -#pragma region power -#endif -/////////////////////////////////////////////////////////////////////////////// -/// @brief Properties related to device power settings -typedef struct _ctl_power_properties_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - bool canControl; ///< [out] Software can change the power limits of this domain assuming the - ///< user has permissions. - int32_t defaultLimit; ///< [out] The factory default TDP power limit of the part in milliwatts. A - ///< value of -1 means that this is not known. - int32_t minLimit; ///< [out] The minimum power limit in milliwatts that can be requested. - int32_t maxLimit; ///< [out] The maximum power limit in milliwatts that can be requested. - -} ctl_power_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Energy counter snapshot -/// -/// @details -/// - Average power is calculated by taking two snapshots (s1, s2) and using -/// the equation: PowerWatts = (s2.energy - s1.energy) / (s2.timestamp - -/// s1.timestamp) -typedef struct _ctl_power_energy_counter_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - uint64_t energy; ///< [out] The monotonic energy counter in microjoules. - uint64_t timestamp; ///< [out] Microsecond timestamp when energy was captured. - ///< 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_power_energy_counter_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Sustained power limits -/// -/// @details -/// - The power controller (Punit) will throttle the operating frequency if -/// the power averaged over a window (typically seconds) exceeds this -/// limit. -typedef struct _ctl_power_sustained_limit_t -{ - bool enabled; ///< [in,out] indicates if the limit is enabled (true) or ignored (false) - int32_t power; ///< [in,out] power limit in milliwatts - int32_t interval; ///< [in,out] power averaging window (Tau) in milliseconds - -} ctl_power_sustained_limit_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Burst power limit -/// -/// @details -/// - The power controller (Punit) will throttle the operating frequency of -/// the device if the power averaged over a few milliseconds exceeds a -/// limit known as PL2. Typically PL2 > PL1 so that it permits the -/// frequency to burst higher for short periods than would be otherwise -/// permitted by PL1. -typedef struct _ctl_power_burst_limit_t -{ - bool enabled; ///< [in,out] indicates if the limit is enabled (true) or ignored (false) - int32_t power; ///< [in,out] power limit in milliwatts - -} ctl_power_burst_limit_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Peak power limit -/// -/// @details -/// - The power controller (Punit) will preemptively throttle the operating -/// frequency of the device when the instantaneous power exceeds this -/// limit. The limit is known as PL4. It expresses the maximum power that -/// can be drawn from the power supply. -/// - If this power limit is removed or set too high, the power supply will -/// generate an interrupt when it detects an overcurrent condition and the -/// power controller will throttle the device frequencies down to min. It -/// is thus better to tune the PL4 value in order to avoid such -/// excursions. -typedef struct _ctl_power_peak_limit_t -{ - int32_t powerAC; ///< [in,out] power limit in milliwatts for the AC power source. - int32_t powerDC; ///< [in,out] power limit in milliwatts for the DC power source. On input, - ///< this is ignored if the product does not have a battery. On output, - ///< this will be -1 if the product does not have a battery. - -} ctl_power_peak_limit_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Power limits -typedef struct _ctl_power_limits_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_power_sustained_limit_t sustainedPowerLimit;///< [in,out] sustained power limit. - ctl_power_burst_limit_t burstPowerLimit; ///< [in,out] burst power limit. - ctl_power_peak_limit_t peakPowerLimits; ///< [in,out] peak power limit. - -} ctl_power_limits_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Energy threshold -/// -/// @details -/// - . -typedef struct _ctl_energy_threshold_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - bool enable; ///< [in,out] Indicates if the energy threshold is enabled. - double threshold; ///< [in,out] The energy threshold in Joules. Will be 0.0 if no threshold - ///< has been set. - uint32_t processId; ///< [in,out] The host process ID that set the energy threshold. Will be - ///< 0xFFFFFFFF if no threshold has been set. - -} ctl_energy_threshold_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get handle of power domains -/// -/// @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 -ctlEnumPowerDomains( - 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_pwr_handle_t* phPower ///< [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 properties related to a power domain -/// -/// @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 == hPower` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pProperties` -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlPowerGetProperties( - ctl_pwr_handle_t hPower, ///< [in] Handle for the component. - ctl_power_properties_t* pProperties ///< [in,out] Structure that will contain property data. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get energy counter -/// -/// @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 == hPower` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pEnergy` -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlPowerGetEnergyCounter( - ctl_pwr_handle_t hPower, ///< [in] Handle for the component. - ctl_power_energy_counter_t* pEnergy ///< [in,out] Will contain the latest snapshot of the energy counter and - ///< timestamp when the last counter value was measured. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get power limits -/// -/// @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 == hPower` -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlPowerGetLimits( - ctl_pwr_handle_t hPower, ///< [in] Handle for the component. - ctl_power_limits_t* pPowerLimits ///< [in,out][optional] Structure that will contain the power limits. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Set power limits -/// -/// @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 == hPower` -/// - ::CTL_RESULT_ERROR_INSUFFICIENT_PERMISSIONS -/// + User does not have permissions to make these modifications. -/// - ::CTL_RESULT_ERROR_NOT_AVAILABLE -/// + The device is in use, meaning that the GPU is under Over clocking, applying power limits under overclocking is not supported. -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlPowerSetLimits( - ctl_pwr_handle_t hPower, ///< [in] Handle for the component. - const ctl_power_limits_t* pPowerLimits ///< [in][optional] Structure that will contain the power limits. - ); - - -#if !defined(__GNUC__) -#pragma endregion // power -#endif -// Intel 'ctlApi' for Device Adapter - Temperature Sensors -#if !defined(__GNUC__) -#pragma region temperature -#endif -/////////////////////////////////////////////////////////////////////////////// -/// @brief Temperature sensors -typedef enum _ctl_temp_sensors_t -{ - CTL_TEMP_SENSORS_GLOBAL = 0, ///< The maximum temperature across all device sensors - CTL_TEMP_SENSORS_GPU = 1, ///< The maximum temperature across all sensors in the GPU - CTL_TEMP_SENSORS_MEMORY = 2, ///< The maximum temperature across all sensors in the local memory - CTL_TEMP_SENSORS_GLOBAL_MIN = 3, ///< The minimum temperature across all device sensors - CTL_TEMP_SENSORS_GPU_MIN = 4, ///< The minimum temperature across all sensors in the GPU - CTL_TEMP_SENSORS_MEMORY_MIN = 5, ///< The minimum temperature across all sensors in the local device memory - CTL_TEMP_SENSORS_MAX - -} ctl_temp_sensors_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Temperature sensor properties -typedef struct _ctl_temp_properties_t -{ - uint32_t Size; ///< [in] size of this structure - uint8_t Version; ///< [in] version of this structure - ctl_temp_sensors_t type; ///< [out] Which part of the device the temperature sensor measures - double maxTemperature; ///< [out] Will contain the maximum temperature for the specific device in - ///< degrees Celsius. - -} ctl_temp_properties_t; - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get handle of temperature sensors -/// -/// @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 -ctlEnumTemperatureSensors( - 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_temp_handle_t* phTemperature ///< [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 temperature sensor 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 == hTemperature` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pProperties` -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlTemperatureGetProperties( - ctl_temp_handle_t hTemperature, ///< [in] Handle for the component. - ctl_temp_properties_t* pProperties ///< [in,out] Will contain the temperature sensor properties. - ); - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Get the temperature from a specified sensor -/// -/// @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 == hTemperature` -/// - CTL_RESULT_ERROR_INVALID_NULL_POINTER -/// + `nullptr == pTemperature` -CTL_APIEXPORT ctl_result_t CTL_APICALL -ctlTemperatureGetState( - ctl_temp_handle_t hTemperature, ///< [in] Handle for the component. - double* pTemperature ///< [in,out] Will contain the temperature read from the specified sensor - ///< in degrees Celsius. - ); - - -#if !defined(__GNUC__) -#pragma endregion // temperature -#endif - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlInit -typedef ctl_result_t (CTL_APICALL *ctl_pfnInit_t)( - ctl_init_args_t*, - ctl_api_handle_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlClose -typedef ctl_result_t (CTL_APICALL *ctl_pfnClose_t)( - ctl_api_handle_t - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlSetRuntimePath -typedef ctl_result_t (CTL_APICALL *ctl_pfnSetRuntimePath_t)( - ctl_runtime_path_args_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlWaitForPropertyChange -typedef ctl_result_t (CTL_APICALL *ctl_pfnWaitForPropertyChange_t)( - ctl_device_adapter_handle_t, - ctl_wait_property_change_args_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlReservedCall -typedef ctl_result_t (CTL_APICALL *ctl_pfnReservedCall_t)( - ctl_device_adapter_handle_t, - ctl_reserved_args_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetSupported3DCapabilities -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSupported3DCapabilities_t)( - ctl_device_adapter_handle_t, - ctl_3d_feature_caps_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetSet3DFeature -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSet3DFeature_t)( - ctl_device_adapter_handle_t, - ctl_3d_feature_getset_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlCheckDriverVersion -typedef ctl_result_t (CTL_APICALL *ctl_pfnCheckDriverVersion_t)( - ctl_device_adapter_handle_t, - ctl_version_info_t - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlEnumerateDevices -typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumerateDevices_t)( - ctl_api_handle_t, - uint32_t*, - ctl_device_adapter_handle_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlEnumerateDisplayOutputs -typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumerateDisplayOutputs_t)( - ctl_device_adapter_handle_t, - uint32_t*, - ctl_display_output_handle_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlEnumerateI2CPinPairs -typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumerateI2CPinPairs_t)( - ctl_device_adapter_handle_t, - uint32_t*, - ctl_i2c_pin_pair_handle_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetDeviceProperties -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetDeviceProperties_t)( - ctl_device_adapter_handle_t, - ctl_device_adapter_properties_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetDisplayProperties -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetDisplayProperties_t)( - ctl_display_output_handle_t, - ctl_display_properties_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetAdaperDisplayEncoderProperties -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetAdaperDisplayEncoderProperties_t)( - ctl_display_output_handle_t, - ctl_adapter_display_encoder_properties_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetZeDevice -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetZeDevice_t)( - ctl_device_adapter_handle_t, - void*, - void** - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetSharpnessCaps -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSharpnessCaps_t)( - ctl_display_output_handle_t, - ctl_sharpness_caps_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetCurrentSharpness -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetCurrentSharpness_t)( - ctl_display_output_handle_t, - ctl_sharpness_settings_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlSetCurrentSharpness -typedef ctl_result_t (CTL_APICALL *ctl_pfnSetCurrentSharpness_t)( - ctl_display_output_handle_t, - ctl_sharpness_settings_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlI2CAccess -typedef ctl_result_t (CTL_APICALL *ctl_pfnI2CAccess_t)( - ctl_display_output_handle_t, - ctl_i2c_access_args_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlI2CAccessOnPinPair -typedef ctl_result_t (CTL_APICALL *ctl_pfnI2CAccessOnPinPair_t)( - ctl_i2c_pin_pair_handle_t, - ctl_i2c_access_pinpair_args_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlAUXAccess -typedef ctl_result_t (CTL_APICALL *ctl_pfnAUXAccess_t)( - ctl_display_output_handle_t, - ctl_aux_access_args_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetPowerOptimizationCaps -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetPowerOptimizationCaps_t)( - ctl_display_output_handle_t, - ctl_power_optimization_caps_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetPowerOptimizationSetting -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetPowerOptimizationSetting_t)( - ctl_display_output_handle_t, - ctl_power_optimization_settings_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlSetPowerOptimizationSetting -typedef ctl_result_t (CTL_APICALL *ctl_pfnSetPowerOptimizationSetting_t)( - ctl_display_output_handle_t, - ctl_power_optimization_settings_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlSetBrightnessSetting -typedef ctl_result_t (CTL_APICALL *ctl_pfnSetBrightnessSetting_t)( - ctl_display_output_handle_t, - ctl_set_brightness_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetBrightnessSetting -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetBrightnessSetting_t)( - ctl_display_output_handle_t, - ctl_get_brightness_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlPixelTransformationGetConfig -typedef ctl_result_t (CTL_APICALL *ctl_pfnPixelTransformationGetConfig_t)( - ctl_display_output_handle_t, - ctl_pixtx_pipe_get_config_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlPixelTransformationSetConfig -typedef ctl_result_t (CTL_APICALL *ctl_pfnPixelTransformationSetConfig_t)( - ctl_display_output_handle_t, - ctl_pixtx_pipe_set_config_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlPanelDescriptorAccess -typedef ctl_result_t (CTL_APICALL *ctl_pfnPanelDescriptorAccess_t)( - ctl_display_output_handle_t, - ctl_panel_descriptor_access_args_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetSupportedRetroScalingCapability -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSupportedRetroScalingCapability_t)( - ctl_device_adapter_handle_t, - ctl_retro_scaling_caps_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetSetRetroScaling -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSetRetroScaling_t)( - ctl_device_adapter_handle_t, - ctl_retro_scaling_settings_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetSupportedScalingCapability -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSupportedScalingCapability_t)( - ctl_display_output_handle_t, - ctl_scaling_caps_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetCurrentScaling -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetCurrentScaling_t)( - ctl_display_output_handle_t, - ctl_scaling_settings_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlSetCurrentScaling -typedef ctl_result_t (CTL_APICALL *ctl_pfnSetCurrentScaling_t)( - ctl_display_output_handle_t, - ctl_scaling_settings_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetLACEConfig -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetLACEConfig_t)( - ctl_display_output_handle_t, - ctl_lace_config_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlSetLACEConfig -typedef ctl_result_t (CTL_APICALL *ctl_pfnSetLACEConfig_t)( - ctl_display_output_handle_t, - ctl_lace_config_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlSoftwarePSR -typedef ctl_result_t (CTL_APICALL *ctl_pfnSoftwarePSR_t)( - ctl_display_output_handle_t, - ctl_sw_psr_settings_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetIntelArcSyncInfoForMonitor -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetIntelArcSyncInfoForMonitor_t)( - ctl_display_output_handle_t, - ctl_intel_arc_sync_monitor_params_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetIntelArcSyncProfile -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetIntelArcSyncProfile_t)( - ctl_display_output_handle_t, - ctl_intel_arc_sync_profile_params_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlSetIntelArcSyncProfile -typedef ctl_result_t (CTL_APICALL *ctl_pfnSetIntelArcSyncProfile_t)( - ctl_display_output_handle_t, - ctl_intel_arc_sync_profile_params_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlEdidManagement -typedef ctl_result_t (CTL_APICALL *ctl_pfnEdidManagement_t)( - ctl_display_output_handle_t, - ctl_edid_management_args_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetSetCustomMode -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSetCustomMode_t)( - ctl_display_output_handle_t, - ctl_get_set_custom_mode_args_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetSetCombinedDisplay -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSetCombinedDisplay_t)( - ctl_device_adapter_handle_t, - ctl_combined_display_args_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetSetDisplayGenlock -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSetDisplayGenlock_t)( - ctl_device_adapter_handle_t*, - ctl_genlock_args_t*, - uint32_t, - ctl_device_adapter_handle_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetVblankTimestamp -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetVblankTimestamp_t)( - ctl_display_output_handle_t, - ctl_vblank_ts_args_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlLinkDisplayAdapters -typedef ctl_result_t (CTL_APICALL *ctl_pfnLinkDisplayAdapters_t)( - ctl_device_adapter_handle_t, - ctl_lda_args_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlUnlinkDisplayAdapters -typedef ctl_result_t (CTL_APICALL *ctl_pfnUnlinkDisplayAdapters_t)( - ctl_device_adapter_handle_t - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetLinkedDisplayAdapters -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetLinkedDisplayAdapters_t)( - ctl_device_adapter_handle_t, - ctl_lda_args_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetSetDynamicContrastEnhancement -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSetDynamicContrastEnhancement_t)( - ctl_display_output_handle_t, - ctl_dce_args_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)( - ctl_device_adapter_handle_t, - uint32_t*, - ctl_engine_handle_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlEngineGetProperties -typedef ctl_result_t (CTL_APICALL *ctl_pfnEngineGetProperties_t)( - ctl_engine_handle_t, - ctl_engine_properties_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlEngineGetActivity -typedef ctl_result_t (CTL_APICALL *ctl_pfnEngineGetActivity_t)( - ctl_engine_handle_t, - ctl_engine_stats_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlEnumFans -typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumFans_t)( - ctl_device_adapter_handle_t, - uint32_t*, - ctl_fan_handle_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlFanGetProperties -typedef ctl_result_t (CTL_APICALL *ctl_pfnFanGetProperties_t)( - ctl_fan_handle_t, - ctl_fan_properties_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlFanGetConfig -typedef ctl_result_t (CTL_APICALL *ctl_pfnFanGetConfig_t)( - ctl_fan_handle_t, - ctl_fan_config_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlFanSetDefaultMode -typedef ctl_result_t (CTL_APICALL *ctl_pfnFanSetDefaultMode_t)( - ctl_fan_handle_t - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlFanSetFixedSpeedMode -typedef ctl_result_t (CTL_APICALL *ctl_pfnFanSetFixedSpeedMode_t)( - ctl_fan_handle_t, - const ctl_fan_speed_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlFanSetSpeedTableMode -typedef ctl_result_t (CTL_APICALL *ctl_pfnFanSetSpeedTableMode_t)( - ctl_fan_handle_t, - const ctl_fan_speed_table_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlFanGetState -typedef ctl_result_t (CTL_APICALL *ctl_pfnFanGetState_t)( - ctl_fan_handle_t, - ctl_fan_speed_units_t, - int32_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)( - ctl_device_adapter_handle_t, - uint32_t*, - ctl_freq_handle_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlFrequencyGetProperties -typedef ctl_result_t (CTL_APICALL *ctl_pfnFrequencyGetProperties_t)( - ctl_freq_handle_t, - ctl_freq_properties_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlFrequencyGetAvailableClocks -typedef ctl_result_t (CTL_APICALL *ctl_pfnFrequencyGetAvailableClocks_t)( - ctl_freq_handle_t, - uint32_t*, - double* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlFrequencyGetRange -typedef ctl_result_t (CTL_APICALL *ctl_pfnFrequencyGetRange_t)( - ctl_freq_handle_t, - ctl_freq_range_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlFrequencySetRange -typedef ctl_result_t (CTL_APICALL *ctl_pfnFrequencySetRange_t)( - ctl_freq_handle_t, - const ctl_freq_range_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlFrequencyGetState -typedef ctl_result_t (CTL_APICALL *ctl_pfnFrequencyGetState_t)( - ctl_freq_handle_t, - ctl_freq_state_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlFrequencyGetThrottleTime -typedef ctl_result_t (CTL_APICALL *ctl_pfnFrequencyGetThrottleTime_t)( - ctl_freq_handle_t, - ctl_freq_throttle_time_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)( - ctl_device_adapter_handle_t, - ctl_video_processing_feature_caps_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlGetSetVideoProcessingFeature -typedef ctl_result_t (CTL_APICALL *ctl_pfnGetSetVideoProcessingFeature_t)( - ctl_device_adapter_handle_t, - ctl_video_processing_feature_getset_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlEnumMemoryModules -typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumMemoryModules_t)( - ctl_device_adapter_handle_t, - uint32_t*, - ctl_mem_handle_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlMemoryGetProperties -typedef ctl_result_t (CTL_APICALL *ctl_pfnMemoryGetProperties_t)( - ctl_mem_handle_t, - ctl_mem_properties_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlMemoryGetState -typedef ctl_result_t (CTL_APICALL *ctl_pfnMemoryGetState_t)( - ctl_mem_handle_t, - ctl_mem_state_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlMemoryGetBandwidth -typedef ctl_result_t (CTL_APICALL *ctl_pfnMemoryGetBandwidth_t)( - ctl_mem_handle_t, - ctl_mem_bandwidth_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlOverclockGetProperties -typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockGetProperties_t)( - ctl_device_adapter_handle_t, - ctl_oc_properties_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlOverclockWaiverSet -typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockWaiverSet_t)( - ctl_device_adapter_handle_t - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlOverclockGpuFrequencyOffsetGet -typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockGpuFrequencyOffsetGet_t)( - ctl_device_adapter_handle_t, - double* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlOverclockGpuFrequencyOffsetSet -typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockGpuFrequencyOffsetSet_t)( - ctl_device_adapter_handle_t, - double - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlOverclockGpuVoltageOffsetGet -typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockGpuVoltageOffsetGet_t)( - ctl_device_adapter_handle_t, - double* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlOverclockGpuVoltageOffsetSet -typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockGpuVoltageOffsetSet_t)( - ctl_device_adapter_handle_t, - double - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlOverclockGpuLockGet -typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockGpuLockGet_t)( - ctl_device_adapter_handle_t, - ctl_oc_vf_pair_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlOverclockGpuLockSet -typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockGpuLockSet_t)( - ctl_device_adapter_handle_t, - ctl_oc_vf_pair_t - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlOverclockVramFrequencyOffsetGet -typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockVramFrequencyOffsetGet_t)( - ctl_device_adapter_handle_t, - double* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlOverclockVramFrequencyOffsetSet -typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockVramFrequencyOffsetSet_t)( - ctl_device_adapter_handle_t, - double - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlOverclockVramVoltageOffsetGet -typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockVramVoltageOffsetGet_t)( - ctl_device_adapter_handle_t, - double* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlOverclockVramVoltageOffsetSet -typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockVramVoltageOffsetSet_t)( - ctl_device_adapter_handle_t, - double - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlOverclockPowerLimitGet -typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockPowerLimitGet_t)( - ctl_device_adapter_handle_t, - double* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlOverclockPowerLimitSet -typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockPowerLimitSet_t)( - ctl_device_adapter_handle_t, - double - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlOverclockTemperatureLimitGet -typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockTemperatureLimitGet_t)( - ctl_device_adapter_handle_t, - double* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlOverclockTemperatureLimitSet -typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockTemperatureLimitSet_t)( - ctl_device_adapter_handle_t, - double - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlPowerTelemetryGet -typedef ctl_result_t (CTL_APICALL *ctl_pfnPowerTelemetryGet_t)( - ctl_device_adapter_handle_t, - ctl_power_telemetry_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlOverclockResetToDefault -typedef ctl_result_t (CTL_APICALL *ctl_pfnOverclockResetToDefault_t)( - ctl_device_adapter_handle_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)( - ctl_device_adapter_handle_t, - ctl_pci_properties_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlPciGetState -typedef ctl_result_t (CTL_APICALL *ctl_pfnPciGetState_t)( - ctl_device_adapter_handle_t, - ctl_pci_state_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlEnumPowerDomains -typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumPowerDomains_t)( - ctl_device_adapter_handle_t, - uint32_t*, - ctl_pwr_handle_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlPowerGetProperties -typedef ctl_result_t (CTL_APICALL *ctl_pfnPowerGetProperties_t)( - ctl_pwr_handle_t, - ctl_power_properties_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlPowerGetEnergyCounter -typedef ctl_result_t (CTL_APICALL *ctl_pfnPowerGetEnergyCounter_t)( - ctl_pwr_handle_t, - ctl_power_energy_counter_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlPowerGetLimits -typedef ctl_result_t (CTL_APICALL *ctl_pfnPowerGetLimits_t)( - ctl_pwr_handle_t, - ctl_power_limits_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlPowerSetLimits -typedef ctl_result_t (CTL_APICALL *ctl_pfnPowerSetLimits_t)( - ctl_pwr_handle_t, - const ctl_power_limits_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlEnumTemperatureSensors -typedef ctl_result_t (CTL_APICALL *ctl_pfnEnumTemperatureSensors_t)( - ctl_device_adapter_handle_t, - uint32_t*, - ctl_temp_handle_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlTemperatureGetProperties -typedef ctl_result_t (CTL_APICALL *ctl_pfnTemperatureGetProperties_t)( - ctl_temp_handle_t, - ctl_temp_properties_t* - ); - - -/////////////////////////////////////////////////////////////////////////////// -/// @brief Function-pointer for ctlTemperatureGetState -typedef ctl_result_t (CTL_APICALL *ctl_pfnTemperatureGetState_t)( - ctl_temp_handle_t, - double* - ); - - -#if defined(__cplusplus) -} // extern "C" -#endif - -#endif // _CTL_API_H \ No newline at end of file diff --git a/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.cpp b/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.cpp index 0fed9c71..9e13e712 100644 --- a/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.cpp @@ -17,7 +17,7 @@ namespace pmon::tel::nvapi NvapiTelemetryProvider::NvapiTelemetryProvider() { try { - pNvapi_ = std::make_unique(); + pNvapi_ = std::make_unique(); } catch (const TelemetrySubsystemAbsent&) { throw; @@ -33,7 +33,7 @@ namespace pmon::tel::nvapi if (enumResult == NVAPI_NVIDIA_DEVICE_NOT_FOUND) { return; } - if (!pwr::nv::NvapiWrapper::Ok(enumResult)) { + if (!NvapiWrapper::Ok(enumResult)) { pmlog_error("NvAPI_EnumPhysicalGPUs failed").code(enumResult); throw Except<>("NVAPI physical GPU enumeration failed"); } @@ -125,7 +125,7 @@ namespace pmon::tel::nvapi NvAPI_ShortString adapterName{}; const auto fullNameResult = pNvapi_->GPU_GetFullName(device.handle, adapterName); - if (pwr::nv::NvapiWrapper::Ok(fullNameResult)) { + if (NvapiWrapper::Ok(fullNameResult)) { device.fingerprint.deviceName = adapterName; } else { @@ -139,7 +139,7 @@ namespace pmon::tel::nvapi NvU32 extDeviceId = 0; const auto pciResult = pNvapi_->GPU_GetPCIIdentifiers( device.handle, &deviceId, &subSystemId, &revisionId, &extDeviceId); - if (pwr::nv::NvapiWrapper::Ok(pciResult)) { + if (NvapiWrapper::Ok(pciResult)) { device.fingerprint.pciDeviceId = deviceId; device.fingerprint.pciSubSystemId = subSystemId; } @@ -151,7 +151,7 @@ namespace pmon::tel::nvapi NvU32 busId = 0; const auto busResult = pNvapi_->GPU_GetBusId(device.handle, &busId); - if (pwr::nv::NvapiWrapper::Ok(busResult)) { + if (NvapiWrapper::Ok(busResult)) { device.fingerprint.pciBusId = busId; } else { @@ -196,11 +196,11 @@ namespace pmon::tel::nvapi if (const auto* pUtilization = PollUtilizationEndpoint_(device, requestQpc)) { if (TryGetUtilizationValue_( - *pUtilization, pwr::nv::NVAPI_GPU_UTILIZATION_DOMAIN_GPU, value)) { + *pUtilization, NVAPI_GPU_UTILIZATION_DOMAIN_GPU, value)) { caps.Set(PM_METRIC_GPU_UTILIZATION, 1); } if (TryGetUtilizationValue_( - *pUtilization, pwr::nv::NVAPI_GPU_UTILIZATION_DOMAIN_VID, value)) { + *pUtilization, NVAPI_GPU_UTILIZATION_DOMAIN_VID, value)) { caps.Set(PM_METRIC_GPU_MEDIA_UTILIZATION, 1); } } @@ -228,7 +228,7 @@ namespace pmon::tel::nvapi const auto result = pNvapi_->GPU_GetThermalSettings( device.handle, NVAPI_THERMAL_TARGET_ALL, &cache.output); - if (!pwr::nv::NvapiWrapper::Ok(result)) { + if (!NvapiWrapper::Ok(result)) { pmlog_warn("NvAPI_GPU_GetThermalSettings failed").code(result).every(std::chrono::seconds{ 60 }) .pmwatch(device.providerDeviceId) .pmwatch(device.fingerprint.deviceName); @@ -254,7 +254,7 @@ namespace pmon::tel::nvapi cache.requestQpc = requestQpc; const auto result = pNvapi_->GPU_GetAllClockFrequencies(device.handle, &cache.output); - if (!pwr::nv::NvapiWrapper::Ok(result)) { + if (!NvapiWrapper::Ok(result)) { pmlog_warn("NvAPI_GPU_GetAllClockFrequencies failed").code(result).every(std::chrono::seconds{ 60 }) .pmwatch(device.providerDeviceId) .pmwatch(device.fingerprint.deviceName); @@ -280,7 +280,7 @@ namespace pmon::tel::nvapi cache.requestQpc = requestQpc; const auto result = pNvapi_->GPU_GetDynamicPstatesInfoEx(device.handle, &cache.output); - if (!pwr::nv::NvapiWrapper::Ok(result)) { + if (!NvapiWrapper::Ok(result)) { pmlog_warn("NvAPI_GPU_GetDynamicPstatesInfoEx failed").code(result).every(std::chrono::seconds{ 60 }) .pmwatch(device.providerDeviceId) .pmwatch(device.fingerprint.deviceName); @@ -305,7 +305,7 @@ namespace pmon::tel::nvapi NvU32 tach = 0; const auto result = pNvapi_->GPU_GetTachReading(device.handle, &tach); - if (!pwr::nv::NvapiWrapper::Ok(result)) { + if (!NvapiWrapper::Ok(result)) { pmlog_warn("NvAPI_GPU_GetTachReading failed").code(result).every(std::chrono::seconds{ 60 }) .pmwatch(device.providerDeviceId) .pmwatch(device.fingerprint.deviceName); @@ -382,7 +382,7 @@ namespace pmon::tel::nvapi const auto* pUtilization = PollUtilizationEndpoint_(device, requestQpc); if (pUtilization && TryGetUtilizationValue_( - *pUtilization, pwr::nv::NVAPI_GPU_UTILIZATION_DOMAIN_GPU, value)) { + *pUtilization, NVAPI_GPU_UTILIZATION_DOMAIN_GPU, value)) { return value; } return 0.0; @@ -393,7 +393,7 @@ namespace pmon::tel::nvapi const auto* pUtilization = PollUtilizationEndpoint_(device, requestQpc); if (pUtilization && TryGetUtilizationValue_( - *pUtilization, pwr::nv::NVAPI_GPU_UTILIZATION_DOMAIN_VID, value)) { + *pUtilization, NVAPI_GPU_UTILIZATION_DOMAIN_VID, value)) { return value; } return 0.0; @@ -457,7 +457,7 @@ namespace pmon::tel::nvapi bool NvapiTelemetryProvider::TryGetUtilizationValue_( const NV_GPU_DYNAMIC_PSTATES_INFO_EX& utilization, - pwr::nv::NVAPI_GPU_UTILIZATION_DOMAIN utilizationDomain, + NVAPI_GPU_UTILIZATION_DOMAIN utilizationDomain, double& value) { if ((size_t)utilizationDomain >= (size_t)NVAPI_MAX_GPU_UTILIZATIONS) { diff --git a/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.h b/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.h index 65326658..546358ae 100644 --- a/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.h +++ b/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.h @@ -3,8 +3,8 @@ #pragma once #include "../EndpointCache.h" -#include "../NvapiWrapper.h" #include "../TelemetryProvider.h" +#include "NvapiWrapper.h" #include #include @@ -76,11 +76,11 @@ namespace pmon::tel::nvapi double& value); static bool TryGetUtilizationValue_( const NV_GPU_DYNAMIC_PSTATES_INFO_EX& utilization, - pwr::nv::NVAPI_GPU_UTILIZATION_DOMAIN utilizationDomain, + NVAPI_GPU_UTILIZATION_DOMAIN utilizationDomain, double& value); private: - std::unique_ptr pNvapi_{}; + std::unique_ptr pNvapi_{}; std::unordered_map devicesById_{}; ProviderDeviceId nextProviderDeviceId_ = 1; }; diff --git a/IntelPresentMon/ControlLib/NvapiWrapper.cpp b/IntelPresentMon/ControlLib/nvapi/NvapiWrapper.cpp similarity index 83% rename from IntelPresentMon/ControlLib/NvapiWrapper.cpp rename to IntelPresentMon/ControlLib/nvapi/NvapiWrapper.cpp index 6f4965c0..ae131bef 100644 --- a/IntelPresentMon/ControlLib/NvapiWrapper.cpp +++ b/IntelPresentMon/ControlLib/nvapi/NvapiWrapper.cpp @@ -1,10 +1,11 @@ -// Copyright (C) 2022 Intel Corporation +// Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: MIT #include "NvapiWrapper.h" #include "nvapi_interface_table.h" #include +#include -namespace pwr::nv +namespace pmon::tel::nvapi { NvapiWrapper::NvapiWrapper() { @@ -62,22 +63,6 @@ namespace pwr::nv } } - NvapiAdapterSignature NvapiWrapper::GetAdapterSignature(NvPhysicalGpuHandle adapter) const noexcept - { - NvapiAdapterSignature signature{}; - - // TODO: log failure - GPU_GetPCIIdentifiers(adapter, - &signature.deviceId, &signature.subSystemId, - &signature.revisionId, &signature.extDeviceId - ); - - // TODO log failure - GPU_GetBusId(adapter, &signature.busId); - - return signature; - } - // definition of wrapper functions // calls function pointer if exists, otherwise return NvAPI error [NVAPI_FUNCTION_NOT_FOUND] #define X_(name, ...) NvAPI_Status NvapiWrapper::name(NVW_ARGS(__VA_ARGS__)) const noexcept \ @@ -87,4 +72,4 @@ namespace pwr::nv } NVW_NVAPI_ENDPOINT_LIST #undef X_ -} \ No newline at end of file +} diff --git a/IntelPresentMon/ControlLib/NvapiWrapper.h b/IntelPresentMon/ControlLib/nvapi/NvapiWrapper.h similarity index 87% rename from IntelPresentMon/ControlLib/NvapiWrapper.h rename to IntelPresentMon/ControlLib/nvapi/NvapiWrapper.h index e67df6b9..ad4b2db6 100644 --- a/IntelPresentMon/ControlLib/NvapiWrapper.h +++ b/IntelPresentMon/ControlLib/nvapi/NvapiWrapper.h @@ -1,11 +1,11 @@ -// Copyright (C) 2022 Intel Corporation +// Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: MIT #pragma once #define NOMINMAX #include +#include "../DllModule.h" +#include "../MacroHelpers.h" #include "nvapi.h" -#include "MacroHelpers.h" -#include "DllModule.h" // goals: single source of truth, automatic id lookup, parameter names in intellisense, easy updates // means: x-macros, macro length overload w/ pairwise operation (up to 6 params) @@ -24,7 +24,7 @@ X_(GPU_GetPCIIdentifiers, NvPhysicalGpuHandle, hPhysicalGpu, NvU32*, pDeviceId, X_(GPU_GetBusId, NvPhysicalGpuHandle, hPhysicalGpu, NvU32*, pBusId) -namespace pwr::nv +namespace pmon::tel::nvapi { // utilization domains are not defined in the public nvapi header enum NVAPI_GPU_UTILIZATION_DOMAIN @@ -35,15 +35,6 @@ namespace pwr::nv NVAPI_GPU_UTILIZATION_DOMAIN_BUS, }; - struct NvapiAdapterSignature - { - NvU32 deviceId; - NvU32 revisionId; - NvU32 subSystemId; - NvU32 extDeviceId; - NvU32 busId; - }; - class NvapiWrapper { public: @@ -56,7 +47,6 @@ namespace pwr::nv NVW_NVAPI_ENDPOINT_LIST #undef X_ static bool Ok(NvAPI_Status sta) noexcept { return sta == NVAPI_OK; } - NvapiAdapterSignature GetAdapterSignature(NvPhysicalGpuHandle adapter) const noexcept; private: DllModule dll{ { "nvapi64.dll", "nvapi32.dll" } }; @@ -67,4 +57,4 @@ namespace pwr::nv // private endpoint pointer NvAPI_Status (*pUnload)() = nullptr; }; -} \ No newline at end of file +} diff --git a/IntelPresentMon/ControlLib/nvapi.h b/IntelPresentMon/ControlLib/nvapi/nvapi.h similarity index 99% rename from IntelPresentMon/ControlLib/nvapi.h rename to IntelPresentMon/ControlLib/nvapi/nvapi.h index 19207664..fa1ca312 100644 --- a/IntelPresentMon/ControlLib/nvapi.h +++ b/IntelPresentMon/ControlLib/nvapi/nvapi.h @@ -1,4 +1,4 @@ -/*****************************************************************************\ +/*****************************************************************************\ |* *| |* Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved. *| |* *| diff --git a/IntelPresentMon/ControlLib/nvapi_interface_table.h b/IntelPresentMon/ControlLib/nvapi/nvapi_interface_table.h similarity index 99% rename from IntelPresentMon/ControlLib/nvapi_interface_table.h rename to IntelPresentMon/ControlLib/nvapi/nvapi_interface_table.h index 4e6dc29a..e0268227 100644 --- a/IntelPresentMon/ControlLib/nvapi_interface_table.h +++ b/IntelPresentMon/ControlLib/nvapi/nvapi_interface_table.h @@ -1,4 +1,4 @@ -/*****************************************************************************\ +/*****************************************************************************\ |* *| |* Copyright (c) 2019-2022, NVIDIA CORPORATION. All rights reserved. *| |* *| diff --git a/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.cpp b/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.cpp index 98facb7d..9ce28514 100644 --- a/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.cpp @@ -16,7 +16,7 @@ namespace pmon::tel::nvml NvmlTelemetryProvider::NvmlTelemetryProvider() { try { - pNvml_ = std::make_unique(); + pNvml_ = std::make_unique(); } catch (...) { pmlog_error(util::ReportException("NVML wrapper construction failed")); @@ -25,7 +25,7 @@ namespace pmon::tel::nvml unsigned int count = 0; const auto countResult = pNvml_->DeviceGetCount_v2(&count); - if (!pwr::nv::NvmlWrapper::Ok(countResult)) { + if (!NvmlWrapper::Ok(countResult)) { pmlog_error("nvmlDeviceGetCount_v2 failed").code(countResult); throw Except<>("NVML device count query failed"); } @@ -33,7 +33,7 @@ namespace pmon::tel::nvml for (unsigned int i = 0; i < count; ++i) { nvmlDevice_t handle = nullptr; const auto handleResult = pNvml_->DeviceGetHandleByIndex_v2(i, &handle); - if (!pwr::nv::NvmlWrapper::Ok(handleResult)) { + if (!NvmlWrapper::Ok(handleResult)) { pmlog_warn("nvmlDeviceGetHandleByIndex_v2 failed").code(handleResult) .pmwatch(i); continue; @@ -178,7 +178,7 @@ namespace pmon::tel::nvml char adapterName[NVML_DEVICE_NAME_BUFFER_SIZE]{}; const auto nameResult = pNvml_->DeviceGetName( device.handle, adapterName, (unsigned int)NVML_DEVICE_NAME_BUFFER_SIZE); - if (!pwr::nv::NvmlWrapper::Ok(nameResult)) { + if (!NvmlWrapper::Ok(nameResult)) { pmlog_warn("nvmlDeviceGetName failed").code(nameResult) .pmwatch(device.providerDeviceId); } @@ -192,7 +192,7 @@ namespace pmon::tel::nvml nvmlPciInfo_t pciInfo{}; const auto pciResult = pNvml_->DeviceGetPciInfo_v3(device.handle, &pciInfo); - if (pwr::nv::NvmlWrapper::Ok(pciResult)) { + if (NvmlWrapper::Ok(pciResult)) { device.fingerprint.pciDeviceId = pciInfo.pciDeviceId; device.fingerprint.pciSubSystemId = pciInfo.pciSubSystemId; device.fingerprint.pciBusId = pciInfo.bus; @@ -248,7 +248,7 @@ namespace pmon::tel::nvml nvmlMemory_t memoryInfo{}; const auto result = pNvml_->DeviceGetMemoryInfo(device.handle, &memoryInfo); - if (!pwr::nv::NvmlWrapper::Ok(result)) { + if (!NvmlWrapper::Ok(result)) { pmlog_warn("nvmlDeviceGetMemoryInfo failed").code(result).every(std::chrono::seconds{ 60 }) .pmwatch(device.providerDeviceId) .pmwatch(device.fingerprint.deviceName); @@ -263,7 +263,7 @@ namespace pmon::tel::nvml { unsigned int powerMw = 0; const auto result = pNvml_->DeviceGetPowerUsage(device.handle, &powerMw); - if (!pwr::nv::NvmlWrapper::Ok(result)) { + if (!NvmlWrapper::Ok(result)) { pmlog_warn("nvmlDeviceGetPowerUsage failed").code(result).every(std::chrono::seconds{ 60 }) .pmwatch(device.providerDeviceId) .pmwatch(device.fingerprint.deviceName); @@ -277,7 +277,7 @@ namespace pmon::tel::nvml { unsigned int limitMw = 0; const auto result = pNvml_->DeviceGetPowerManagementLimit(device.handle, &limitMw); - if (!pwr::nv::NvmlWrapper::Ok(result)) { + if (!NvmlWrapper::Ok(result)) { pmlog_warn("nvmlDeviceGetPowerManagementLimit failed").code(result).every(std::chrono::seconds{ 60 }) .pmwatch(device.providerDeviceId) .pmwatch(device.fingerprint.deviceName); diff --git a/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.h b/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.h index 7a34c865..80a110a1 100644 --- a/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.h +++ b/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.h @@ -3,8 +3,8 @@ #pragma once #include "../EndpointCache.h" -#include "../NvmlWrapper.h" #include "../TelemetryProvider.h" +#include "NvmlWrapper.h" #include #include @@ -51,7 +51,7 @@ namespace pmon::tel::nvml std::optional PollPowerLimitEndpoint_(const DeviceState_& device) const; private: - std::unique_ptr pNvml_{}; + std::unique_ptr pNvml_{}; std::unordered_map devicesById_{}; ProviderDeviceId nextProviderDeviceId_ = 1; }; diff --git a/IntelPresentMon/ControlLib/NvmlWrapper.cpp b/IntelPresentMon/ControlLib/nvml/NvmlWrapper.cpp similarity index 56% rename from IntelPresentMon/ControlLib/NvmlWrapper.cpp rename to IntelPresentMon/ControlLib/nvml/NvmlWrapper.cpp index f176dd87..ec6c4e35 100644 --- a/IntelPresentMon/ControlLib/NvmlWrapper.cpp +++ b/IntelPresentMon/ControlLib/nvml/NvmlWrapper.cpp @@ -1,9 +1,8 @@ -// Copyright (C) 2022 Intel Corporation +// Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: MIT #include "NvmlWrapper.h" -#include -namespace pwr::nv +namespace pmon::tel::nvml { NvmlWrapper::NvmlWrapper() { @@ -40,43 +39,6 @@ namespace pwr::nv } } - NvmlAdapterSignature NvmlWrapper::GetAdapterSignature(nvmlDevice_t adapter) const - { - // get pci information - nvmlPciInfo_t pciInfo{}; - if (!Ok(DeviceGetPciInfo_v3(adapter, &pciInfo))) - { - // TODO: log failure of this function - return {}; - } - - // fill directly fillable information into signature - NvmlAdapterSignature signature{ - .pciDeviceId = pciInfo.pciDeviceId, - .pciSubSystemId = pciInfo.pciSubSystemId, - }; - - // extract out necessary components from pciInfo. - // pciInfo.busId is a string with format = Domain:Bus:PciFunction.Id - try { - const std::regex expr{ "(.*?):(.*?):(.*?)\\.(.*)" }; - std::cmatch results; - if (std::regex_match(pciInfo.busId, results, expr)) - { - if (results[1].length() > 0) - { - signature.busIdDomain = std::stoul(results[1]); - } - if (results[2].length() > 0) - { - signature.busIdBus = std::stoul(results[2]); - } - } - } catch (...) {} - - return signature; - } - // definition of wrapper functions // calls function pointer if exists, otherwise return NVML error [NVML_ERROR_FUNCTION_NOT_FOUND] #define X_(name, ...) nvmlReturn_t NvmlWrapper::name(NVW_ARGS(__VA_ARGS__)) const noexcept \ @@ -86,4 +48,4 @@ namespace pwr::nv } NVW_NVML_ENDPOINT_LIST #undef X_ -} \ No newline at end of file +} diff --git a/IntelPresentMon/ControlLib/NvmlWrapper.h b/IntelPresentMon/ControlLib/nvml/NvmlWrapper.h similarity index 88% rename from IntelPresentMon/ControlLib/NvmlWrapper.h rename to IntelPresentMon/ControlLib/nvml/NvmlWrapper.h index b0e1773e..358aa832 100644 --- a/IntelPresentMon/ControlLib/NvmlWrapper.h +++ b/IntelPresentMon/ControlLib/nvml/NvmlWrapper.h @@ -1,9 +1,9 @@ // Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: MIT #pragma once +#include "../DllModule.h" +#include "../MacroHelpers.h" #include "nvml.h" -#include "DllModule.h" -#include "MacroHelpers.h" // goals: single source of truth, automatic id lookup, parameter names in intellisense, easy updates // means: x-macros, macro length overload w/ pairwise operation (up to 6 params) @@ -23,22 +23,13 @@ X_(DeviceGetEnforcedPowerLimit, nvmlDevice_t, device, unsigned int*, limit) \ X_(DeviceGetPowerManagementLimit, nvmlDevice_t, device, unsigned int*, limit) \ X_(DeviceGetViolationStatus, nvmlDevice_t, device, nvmlPerfPolicyType_t, perfPolicyType, nvmlViolationTime_t*, violTime) -namespace pwr::nv +namespace pmon::tel::nvml { - struct NvmlAdapterSignature - { - uint32_t busIdDomain; - uint32_t busIdBus; - uint32_t pciDeviceId; - uint32_t pciSubSystemId; - }; - class NvmlWrapper { public: NvmlWrapper(); ~NvmlWrapper(); - NvmlAdapterSignature GetAdapterSignature(nvmlDevice_t adapter) const; static bool Ok(nvmlReturn_t sta) noexcept { return sta == nvmlReturn_t::NVML_SUCCESS; } // endpoint wrapper functions #define X_(name, ...) nvmlReturn_t name(NVW_ARGS(__VA_ARGS__)) const noexcept; diff --git a/IntelPresentMon/ControlLib/nvml.h b/IntelPresentMon/ControlLib/nvml/nvml.h similarity index 100% rename from IntelPresentMon/ControlLib/nvml.h rename to IntelPresentMon/ControlLib/nvml/nvml.h diff --git a/IntelPresentMon/Interprocess/Interprocess.vcxproj b/IntelPresentMon/Interprocess/Interprocess.vcxproj index 48c9dcd9..9e2c5b65 100644 --- a/IntelPresentMon/Interprocess/Interprocess.vcxproj +++ b/IntelPresentMon/Interprocess/Interprocess.vcxproj @@ -17,7 +17,6 @@ - @@ -33,9 +32,7 @@ - - @@ -175,4 +172,4 @@ - \ No newline at end of file + diff --git a/IntelPresentMon/Interprocess/Interprocess.vcxproj.filters b/IntelPresentMon/Interprocess/Interprocess.vcxproj.filters index 34a52430..82ad79fe 100644 --- a/IntelPresentMon/Interprocess/Interprocess.vcxproj.filters +++ b/IntelPresentMon/Interprocess/Interprocess.vcxproj.filters @@ -33,9 +33,6 @@ Source Files - - Source Files - Source Files @@ -107,9 +104,6 @@ Header Files - - Header Files - Header Files @@ -179,11 +173,8 @@ Header Files - - Header Files - Header Files - \ No newline at end of file + diff --git a/IntelPresentMon/Interprocess/source/Interprocess.h b/IntelPresentMon/Interprocess/source/Interprocess.h index 3d67d92e..54074f96 100644 --- a/IntelPresentMon/Interprocess/source/Interprocess.h +++ b/IntelPresentMon/Interprocess/source/Interprocess.h @@ -1,9 +1,7 @@ -#pragma once +#pragma once #include #include #include -#include "../../ControlLib/PresentMonPowerTelemetry.h" -#include "../../ControlLib/CpuTelemetryInfo.h" #include "../../PresentMonAPI2/PresentMonAPI.h" #include "DataStores.h" #include "OwnedDataSegment.h" @@ -56,4 +54,4 @@ namespace pmon::ipc size_t frameRingSamples, size_t telemetryRingSamples); std::unique_ptr MakeMiddlewareComms(std::string prefix, std::string salt); -} \ No newline at end of file +} diff --git a/IntelPresentMon/Interprocess/source/IntrospectionCapsLookup.h b/IntelPresentMon/Interprocess/source/IntrospectionCapsLookup.h deleted file mode 100644 index 1062c9ab..00000000 --- a/IntelPresentMon/Interprocess/source/IntrospectionCapsLookup.h +++ /dev/null @@ -1,91 +0,0 @@ -#pragma once -#include "IntrospectionMetadata.h" -#include -#include "../../ControlLib/PresentMonPowerTelemetry.h" -#include "../../ControlLib/CpuTelemetryInfo.h" - - -namespace pmon::ipc::intro -{ - // mapping of caps to metrics - template struct IntrospectionCapsLookup { using Universal = std::true_type; }; - // sentinel metric used for enumeration only (no availability) - template<> struct IntrospectionCapsLookup {}; - // GPU caps - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_power; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_voltage; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_temperature; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_frequency; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_effective_frequency; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_utilization; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_render_compute_utilization; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_media_utilization; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::vram_power; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::vram_voltage; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::vram_frequency; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::vram_effective_frequency; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::vram_temperature; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_voltage_regulator_temperature; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_mem_effective_bandwidth; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_overvoltage_percent; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_temperature_percent; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_power_percent; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_card_power; }; - template<> struct IntrospectionCapsLookup { - static constexpr auto gpuCapBitArray = std::array{ GpuTelemetryCapBits::fan_speed_0, GpuTelemetryCapBits::fan_speed_1, - GpuTelemetryCapBits::fan_speed_2, GpuTelemetryCapBits::fan_speed_3, GpuTelemetryCapBits::fan_speed_4, }; - }; - template<> struct IntrospectionCapsLookup { - using Derived = std::true_type; - static constexpr auto gpuCapBitArray = std::array{ GpuTelemetryCapBits::max_fan_speed_0, GpuTelemetryCapBits::max_fan_speed_1, - GpuTelemetryCapBits::max_fan_speed_2, GpuTelemetryCapBits::max_fan_speed_3, GpuTelemetryCapBits::max_fan_speed_4, }; - }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_mem_used; }; - template<> struct IntrospectionCapsLookup { - using Derived = std::true_type; - static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_mem_used; - }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_mem_write_bandwidth; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_mem_read_bandwidth; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_power_limited; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_temperature_limited; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_current_limited; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_voltage_limited; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_utilization_limited; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::vram_power_limited; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::vram_temperature_limited; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::vram_current_limited; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::vram_voltage_limited; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::vram_utilization_limited; }; - // static GPU - // TODO: static and cap bit signalling are NOT mutually exclusive!! - template<> struct IntrospectionCapsLookup { using GpuDeviceStatic = std::true_type; }; - template<> struct IntrospectionCapsLookup { using GpuDeviceStatic = std::true_type; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_sustained_power_limit; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_mem_size; }; - template<> struct IntrospectionCapsLookup { static constexpr auto gpuCapBit = GpuTelemetryCapBits::gpu_mem_max_bandwidth; }; - // CPU caps - template<> struct IntrospectionCapsLookup { static constexpr auto cpuCapBit = CpuTelemetryCapBits::cpu_utilization; }; - template<> struct IntrospectionCapsLookup { static constexpr auto cpuCapBit = CpuTelemetryCapBits::cpu_power; }; - template<> struct IntrospectionCapsLookup { static constexpr auto cpuCapBit = CpuTelemetryCapBits::cpu_temperature; }; - template<> struct IntrospectionCapsLookup { static constexpr auto cpuCapBit = CpuTelemetryCapBits::cpu_frequency; }; - template<> struct IntrospectionCapsLookup { using ManualDisable = std::true_type; - static constexpr auto cpuCapBit = CpuTelemetryCapBits::cpu_core_utility; - }; - // static CPU - template<> struct IntrospectionCapsLookup { static constexpr auto cpuCapBit = CpuTelemetryCapBits::cpu_power_limit; }; - template<> struct IntrospectionCapsLookup { using CpuStatic = std::true_type; }; - template<> struct IntrospectionCapsLookup { using CpuStatic = std::true_type; }; - // TODO: consider additional static CPU metrics beyond name/vendor. - - - // concepts to help determine device-metric mapping type - template concept IsUniversalMetric = requires { typename T::Universal; }; - template concept IsGpuDeviceMetric = requires { T::gpuCapBit; }; - template concept IsGpuDeviceMetricArray = requires { T::gpuCapBitArray; }; - template concept IsGpuDeviceStaticMetric = requires { typename T::GpuDeviceStatic; }; - template concept IsCpuMetric = requires { T::cpuCapBit; }; - template concept IsCpuStaticMetric = requires { typename T::CpuStatic; }; - template concept IsManualDisableMetric = requires { typename T::ManualDisable; }; - template concept IsDerivedMetric = requires { typename T::Derived; }; -} diff --git a/IntelPresentMon/Interprocess/source/IntrospectionPopulators.cpp b/IntelPresentMon/Interprocess/source/IntrospectionPopulators.cpp index fcc37430..af3e64fa 100644 --- a/IntelPresentMon/Interprocess/source/IntrospectionPopulators.cpp +++ b/IntelPresentMon/Interprocess/source/IntrospectionPopulators.cpp @@ -1,7 +1,6 @@ -#include "IntrospectionHelpers.h" +#include "IntrospectionHelpers.h" #include "IntrospectionMetadata.h" #include "IntrospectionTransfer.h" -#include "IntrospectionCapsLookup.h" #include "MetricCapabilities.h" #include "IntrospectionPopulators.h" #include "../../CommonUtilities/log/Log.h" @@ -30,11 +29,10 @@ namespace pmon::ipc::intro #undef X_REG_KEYS } - template + template void RegisterUniversalMetricDeviceInfo_(ShmSegmentManager* pSegmentManager, IntrospectionRoot& root, IntrospectionMetric& metric) { - using Lookup = IntrospectionCapsLookup; - if constexpr (IsUniversalMetric) { + if constexpr (deviceType == PM_DEVICE_TYPE_INDEPENDENT) { metric.AddDeviceMetricInfo(IntrospectionDeviceMetricInfo{ 0, PM_METRIC_AVAILABILITY_AVAILABLE, 1 }); } @@ -52,7 +50,7 @@ namespace pmon::ipc::intro #define X_REG_METRIC(metric, metric_type, unit, data_type_polled, data_type_frame, enum_id, device_type, ...) { \ auto pMetric = ShmMakeUnique(pSegmentManager, pSegmentManager, \ metric, metric_type, unit, IntrospectionDataTypeInfo{ data_type_polled, data_type_frame, (PM_ENUM)enum_id }, std::vector{ __VA_ARGS__ }); \ - RegisterUniversalMetricDeviceInfo_(pSegmentManager, root, *pMetric); \ + RegisterUniversalMetricDeviceInfo_(pSegmentManager, root, *pMetric); \ if (preferredMetricOverrides.contains(metric)) pMetric->SetPreferredUnitHint(preferredMetricOverrides[metric]); \ root.AddMetric(std::move(pMetric)); } diff --git a/IntelPresentMon/Interprocess/source/MetricCapabilitiesShim.cpp b/IntelPresentMon/Interprocess/source/MetricCapabilitiesShim.cpp deleted file mode 100644 index 373abe98..00000000 --- a/IntelPresentMon/Interprocess/source/MetricCapabilitiesShim.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include "MetricCapabilitiesShim.h" -#include "IntrospectionCapsLookup.h" -#include "../../CommonUtilities/Meta.h" -#include - -namespace pmon::ipc::intro -{ - namespace detail - { - using MetricEnum = PM_METRIC; - // Probe underlying values in [0, COUNT) - constexpr auto MaxMetricUnderlying = int(PM_METRIC_COUNT_); - - // xxxCapBits is std::bitset - template - bool HasCap(const BitsType& bits, Index index) - { - return bits.test(static_cast(index)); - } - - template - size_t CountGpuCaps_(const GpuTelemetryBitset& bits, const ArrayT& caps) - { - size_t count = 0; - for (auto flag : caps) { - if (HasCap(bits, flag)) { - ++count; - } - } - return count; - } - - // GPU per-metric accumulation (only instantiated for valid enum values) - template - void AccumulateGpuCapability(MetricCapabilities& caps, const GpuTelemetryBitset& bits) - { - using Lookup = IntrospectionCapsLookup; - - if constexpr (IsDerivedMetric) { - return; - } - - // Single GPU capability bit -> metric present if bit set - if constexpr (IsGpuDeviceMetric) { - if (HasCap(bits, Lookup::gpuCapBit)) { - caps.Set(Metric, 1); - } - } - - // Array GPU capability bits (fan speeds, etc.) - if constexpr (IsGpuDeviceMetricArray && !IsManualDisableMetric) { - std::size_t count = 0; - for (auto flag : Lookup::gpuCapBitArray) { - if (HasCap(bits, flag)) { - ++count; - } - } - if (count > 0) { - caps.Set(Metric, count); - } - } - - // Static GPU metrics: name/vendor/etc. - if constexpr (IsGpuDeviceStaticMetric) { - caps.Set(Metric, 1); - } - } - - void AccumulateDerivedGpuCapabilities_(MetricCapabilities& caps, const GpuTelemetryBitset& bits) - { - const auto fanCount = caps.Check(PM_METRIC_GPU_FAN_SPEED); - const auto maxFanCount = CountGpuCaps_(bits, - IntrospectionCapsLookup::gpuCapBitArray); - const auto derivedFanCount = std::min(fanCount, maxFanCount); - if (derivedFanCount > 0) { - caps.Set(PM_METRIC_GPU_FAN_SPEED_PERCENT, derivedFanCount); - } - - if (caps.Check(PM_METRIC_GPU_MEM_USED) > 0 && - caps.Check(PM_METRIC_GPU_MEM_SIZE) > 0) { - caps.Set(PM_METRIC_GPU_MEM_UTILIZATION, 1); - } - } - - // CPU per-metric accumulation (only instantiated for valid enum values) - template - void AccumulateCpuCapability(MetricCapabilities& caps, const CpuTelemetryBitset& bits) - { - using Lookup = IntrospectionCapsLookup; - - // CPU metrics gated by a capability bit - if constexpr (IsCpuMetric && !IsManualDisableMetric) { - if (HasCap(bits, Lookup::cpuCapBit)) { - caps.Set(Metric, 1); - } - } - - if constexpr (IsCpuStaticMetric) { - caps.Set(Metric, 1); - } - } - } // namespace detail - - MetricCapabilities ConvertBitset(const GpuTelemetryBitset& bits) - { - MetricCapabilities caps; - util::ForEachEnumValue( - [&]() { - detail::AccumulateGpuCapability(caps, bits); - }); - detail::AccumulateDerivedGpuCapabilities_(caps, bits); - return caps; - } - - MetricCapabilities ConvertBitset(const CpuTelemetryBitset& bits) - { - MetricCapabilities caps; - util::ForEachEnumValue( - [&]() { - detail::AccumulateCpuCapability(caps, bits); - }); - return caps; - } -} diff --git a/IntelPresentMon/Interprocess/source/MetricCapabilitiesShim.h b/IntelPresentMon/Interprocess/source/MetricCapabilitiesShim.h deleted file mode 100644 index d0fba726..00000000 --- a/IntelPresentMon/Interprocess/source/MetricCapabilitiesShim.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "MetricCapabilities.h" -#include "../../ControlLib/PresentMonPowerTelemetry.h" -#include "../../ControlLib/CpuTelemetryInfo.h" - -namespace pmon::ipc::intro -{ - MetricCapabilities ConvertBitset(const GpuTelemetryBitset& bits); - MetricCapabilities ConvertBitset(const CpuTelemetryBitset& bits); -} \ No newline at end of file diff --git a/IntelPresentMon/PresentMonService/LogSetup.cpp b/IntelPresentMon/PresentMonService/LogSetup.cpp index e6592c9a..7f0fd92c 100644 --- a/IntelPresentMon/PresentMonService/LogSetup.cpp +++ b/IntelPresentMon/PresentMonService/LogSetup.cpp @@ -1,4 +1,4 @@ -#include "LogSetup.h" +#include "LogSetup.h" #include #include "../CommonUtilities/log/Log.h" #include "../CommonUtilities/log/Channel.h" @@ -16,7 +16,7 @@ #include "../CommonUtilities/win/HrErrorCodeProvider.h" #include "../CommonUtilities/str/String.h" #include "../CommonUtilities/Exception.h" -#include "../ControlLib/IgclErrorCodeProvider.h" +#include "../ControlLib/igcl/IgclErrorCodeProvider.h" #include "../PresentMonAPIWrapperCommon/PmErrorCodeProvider.h" #include "CliOptions.h" #include "Registry.h" @@ -33,7 +33,7 @@ namespace pmon::util::log // error resolver auto pErrorResolver = std::make_shared(); pErrorResolver->AddProvider(std::make_unique()); - pErrorResolver->AddProvider(std::make_unique()); + pErrorResolver->AddProvider(std::make_unique()); pErrorResolver->AddProvider(std::make_unique()); // error resolving policy auto pErrPolicy = std::make_shared(); diff --git a/IntelPresentMon/PresentMonService/MetricUse.h b/IntelPresentMon/PresentMonService/MetricUse.h index c004c07b..9a2af2be 100644 --- a/IntelPresentMon/PresentMonService/MetricUse.h +++ b/IntelPresentMon/PresentMonService/MetricUse.h @@ -1,3 +1,60 @@ -#pragma once +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#pragma once -#include "../ControlLib/MetricUse.h" +// NOTE: This file must remain header-only because ControlLib depends on these +// types even though ControlLib does not have a symbol link dependency on the +// PresentMonService project. + +#include "../CommonUtilities/Hash.h" +#include "../PresentMonAPI2/PresentMonAPI.h" +#include +#include +#include +#include +#include + +namespace pmon::svc +{ + struct MetricUse + { + PM_METRIC metricId; + uint32_t deviceId; + uint32_t arrayIdx; + + template + void serialize(A& ar) + { + ar(CEREAL_NVP(metricId), + CEREAL_NVP(deviceId), + CEREAL_NVP(arrayIdx)); + } + + bool operator==(const MetricUse& rhs) const + { + return metricId == rhs.metricId && + deviceId == rhs.deviceId && + arrayIdx == rhs.arrayIdx; + } + }; + + using DeviceMetricUse = std::unordered_map>; +} + +namespace std +{ + template<> + struct hash + { + size_t operator()(const pmon::svc::MetricUse& mu) const noexcept + { + const uint64_t devIdx = + (uint64_t(mu.deviceId) << 32) | uint64_t(mu.arrayIdx); + + using Under = std::underlying_type_t; + const Under mid = (Under)mu.metricId; + + return pmon::util::hash::DualHash(mid, devIdx); + } + }; +} diff --git a/IntelPresentMon/PresentMonService/PMMainThread.cpp b/IntelPresentMon/PresentMonService/PMMainThread.cpp index 55229c1f..a02cafb6 100644 --- a/IntelPresentMon/PresentMonService/PMMainThread.cpp +++ b/IntelPresentMon/PresentMonService/PMMainThread.cpp @@ -130,6 +130,10 @@ void TelemetryThreadEntry_(Service* const srv, PresentMon* const pm, ipc::Servic pmon::tel::TelemetryCoordinator coordinator; coordinator.RegisterDevicesToIpc(*pComms); coordinator.PopulateStaticsToIpc(*pComms); + if (const auto cpuInfo = coordinator.GetCpuInfo()) { + pm->SetCpuStaticInfo(cpuInfo->name, cpuInfo->cpuPowerLimit); + } + pm->SetTelemetryAdapters(coordinator.EnumerateAdapters()); pmlog_info(std::format( "Finished populating telemetry introspection, {} seconds elapsed", timer.Mark())); diff --git a/IntelPresentMon/PresentMonService/PowerTelemetryContainer.cpp b/IntelPresentMon/PresentMonService/PowerTelemetryContainer.cpp deleted file mode 100644 index 2bbb1282..00000000 --- a/IntelPresentMon/PresentMonService/PowerTelemetryContainer.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "PowerTelemetryContainer.h" -#include "../ControlLib/Exceptions.h" -#include -#include -#include - -#include "../CommonUtilities/log/GlogShim.h" - -bool PowerTelemetryContainer::Repopulate() { - try { - telemetry_providers_.clear(); - telemetry_adapters_.clear(); - - // create providers - for (int iVendor = 0; iVendor < int(PM_DEVICE_VENDOR_UNKNOWN); iVendor++) { - try { - if (auto pProvider = pwr::PowerTelemetryProviderFactory::Make( - PM_DEVICE_VENDOR(iVendor), device_id_allocator_)) { - telemetry_providers_.push_back(std::move(pProvider)); - } - } - catch (const TelemetrySubsystemAbsent& e) { - LOG(INFO) << "Skipping Telemetry Provider: " << e.what(); - } - catch (const std::runtime_error& e) { - LOG(INFO) << "Power Telemetry Failure: " << e.what(); - } - catch (...) { - LOG(INFO) << "Unknown Telemetry Failure."; - } - } - // collect all adapters together from providers - for (const auto& pProvider : telemetry_providers_) { - auto& adapters = pProvider->GetAdapters(); - telemetry_adapters_.insert(telemetry_adapters_.end(), adapters.begin(), - adapters.end()); - } - // bail if there are not adapters - if (telemetry_adapters_.size() == 0) { - return false; - } - // Re-sort adapters based on video memory size in an attempt to return back the most - // capable adapters - constexpr auto ComparisonField = &pwr::PowerTelemetryAdapter::GetDedicatedVideoMemory; - std::ranges::sort(telemetry_adapters_, std::greater{}, ComparisonField); - return true; - } - catch (...) { - return false; - } -} diff --git a/IntelPresentMon/PresentMonService/PowerTelemetryContainer.h b/IntelPresentMon/PresentMonService/PowerTelemetryContainer.h deleted file mode 100644 index 75e199a6..00000000 --- a/IntelPresentMon/PresentMonService/PowerTelemetryContainer.h +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -#pragma once -#include "../ControlLib/PowerTelemetryProviderFactory.h" -#include "../ControlLib/DeviceIdAllocator.h" - -class PowerTelemetryContainer { - public: - const std::vector>& - GetPowerTelemetryAdapters() { - return telemetry_adapters_; - } - bool Repopulate(); - private: - std::vector> telemetry_providers_; - std::vector> telemetry_adapters_; - pwr::DeviceIdAllocator device_id_allocator_; -}; diff --git a/IntelPresentMon/PresentMonService/PresentMon.cpp b/IntelPresentMon/PresentMonService/PresentMon.cpp index 8d6bdedf..a1d288ab 100644 --- a/IntelPresentMon/PresentMonService/PresentMon.cpp +++ b/IntelPresentMon/PresentMonService/PresentMon.cpp @@ -38,9 +38,8 @@ PM_STATUS PresentMon::UpdateTracking(const std::unordered_set& tracked return pSession_->UpdateTracking(trackedPids); } -std::vector> PresentMon::EnumerateAdapters() +std::vector PresentMon::EnumerateAdapters() const { - // Only the real time trace uses the control libary interface return pSession_->EnumerateAdapters(); } diff --git a/IntelPresentMon/PresentMonService/PresentMon.h b/IntelPresentMon/PresentMonService/PresentMon.h index b5e77341..e6f69dd0 100644 --- a/IntelPresentMon/PresentMonService/PresentMon.h +++ b/IntelPresentMon/PresentMonService/PresentMon.h @@ -37,7 +37,7 @@ class PresentMon // Force stop trace sessions void StopTraceSessions(); PM_STATUS UpdateTracking(const std::unordered_set& trackedPids); - std::vector> EnumerateAdapters(); + std::vector EnumerateAdapters() const; std::string GetCpuName() { return pSession_->GetCpuName(); } double GetCpuPowerLimit() { return pSession_->GetCpuPowerLimit(); } PM_STATUS SetGpuTelemetryPeriod(std::optional telemetryPeriodRequestsMs) @@ -59,10 +59,9 @@ class PresentMon // Only the real time trace sets ETW flush period return pSession_->GetEtwFlushPeriod(); } - void SetCpu(const std::shared_ptr& pCpu) + void SetCpuStaticInfo(std::string cpuName, double cpuPowerLimit) { - // Only the real time trace uses the control libary interface - pSession_->SetCpu(pCpu); + pSession_->SetCpuStaticInfo(std::move(cpuName), cpuPowerLimit); } HANDLE GetStreamingStartHandle() { @@ -72,10 +71,9 @@ class PresentMon { return pSession_->HasLiveTargets(); } - void SetPowerTelemetryContainer(PowerTelemetryContainer* ptc) + void SetTelemetryAdapters(std::vector adapters) { - // Only the real time trace session uses the control library interface - return pSession_->SetPowerTelemetryContainer(ptc); + pSession_->SetTelemetryAdapters(std::move(adapters)); } void FlushEvents() { diff --git a/IntelPresentMon/PresentMonService/PresentMonService.vcxproj b/IntelPresentMon/PresentMonService/PresentMonService.vcxproj index 9121f5d8..e59482eb 100644 --- a/IntelPresentMon/PresentMonService/PresentMonService.vcxproj +++ b/IntelPresentMon/PresentMonService/PresentMonService.vcxproj @@ -122,7 +122,6 @@ - @@ -155,7 +154,6 @@ - diff --git a/IntelPresentMon/PresentMonService/PresentMonService.vcxproj.filters b/IntelPresentMon/PresentMonService/PresentMonService.vcxproj.filters index efe8e1c7..cba62482 100644 --- a/IntelPresentMon/PresentMonService/PresentMonService.vcxproj.filters +++ b/IntelPresentMon/PresentMonService/PresentMonService.vcxproj.filters @@ -3,7 +3,6 @@ - @@ -20,7 +19,6 @@ - diff --git a/IntelPresentMon/PresentMonService/PresentMonSession.cpp b/IntelPresentMon/PresentMonService/PresentMonSession.cpp index f05410ef..d2ece4c8 100644 --- a/IntelPresentMon/PresentMonService/PresentMonSession.cpp +++ b/IntelPresentMon/PresentMonService/PresentMonSession.cpp @@ -26,35 +26,21 @@ pmon::test::service::Status PresentMonSession::GetTestingStatus() const }; } -void PresentMonSession::SetCpu(const std::shared_ptr& pCpu) { - cpu_ = pCpu.get(); +std::vector PresentMonSession::EnumerateAdapters() const { + return telemetry_adapters_; } -std::vector> PresentMonSession::EnumerateAdapters() { - if (telemetry_container_) { - return telemetry_container_->GetPowerTelemetryAdapters(); - } - else { - return {}; - } +void PresentMonSession::SetCpuStaticInfo(std::string cpuName, double cpuPowerLimit) { + cpu_name_ = std::move(cpuName); + cpu_power_limit_ = cpuPowerLimit; } std::string PresentMonSession::GetCpuName() { - if (cpu_) { - return cpu_->GetCpuName(); - } - else { - return std::string{ "UNKOWN_CPU" }; - } + return cpu_name_.empty() ? std::string{ "UNKOWN_CPU" } : cpu_name_; } double PresentMonSession::GetCpuPowerLimit() { - if (cpu_) { - return cpu_->GetCpuPowerLimit(); - } - else { - return 0.; - } + return cpu_power_limit_; } PM_STATUS PresentMonSession::SetGpuTelemetryPeriod(std::optional period_ms) @@ -87,8 +73,9 @@ bool PresentMonSession::HasLiveTargets() const { return HasLiveTrackedProcesses(); } -void PresentMonSession::SetPowerTelemetryContainer(PowerTelemetryContainer* ptc) { - telemetry_container_ = ptc; +void PresentMonSession::SetTelemetryAdapters( + std::vector adapters) { + telemetry_adapters_ = std::move(adapters); } void PresentMonSession::SyncTrackedPidState(const std::unordered_set& trackedPids) diff --git a/IntelPresentMon/PresentMonService/PresentMonSession.h b/IntelPresentMon/PresentMonService/PresentMonSession.h index 9545a4ff..7ef55e57 100644 --- a/IntelPresentMon/PresentMonService/PresentMonSession.h +++ b/IntelPresentMon/PresentMonService/PresentMonSession.h @@ -14,11 +14,9 @@ #include #include -#include "../ControlLib/PowerTelemetryProvider.h" -#include "../ControlLib/CpuTelemetry.h" +#include "../ControlLib/TelemetryCoordinator.h" #include "../../PresentData/PresentMonTraceConsumer.hpp" #include "../../PresentData/PresentMonTraceSession.hpp" -#include "PowerTelemetryContainer.h" #include "FrameBroadcaster.h" #include "../PresentMonAPI2Tests/TestCommands.h" @@ -41,8 +39,8 @@ class PresentMonSession { virtual void FlushEvents() {} virtual void ResetEtwFlushPeriod() = 0; - void SetCpu(const std::shared_ptr& pCpu); - std::vector> EnumerateAdapters(); + std::vector EnumerateAdapters() const; + void SetCpuStaticInfo(std::string cpuName, double cpuPowerLimit); std::string GetCpuName(); double GetCpuPowerLimit(); pmon::test::service::Status GetTestingStatus() const; @@ -51,7 +49,7 @@ class PresentMonSession { std::optional GetEtwFlushPeriod(); uint32_t GetGpuTelemetryPeriod(); bool HasLiveTargets() const; - void SetPowerTelemetryContainer(PowerTelemetryContainer* ptc); + void SetTelemetryAdapters(std::vector adapters); void MarkProcessExited(uint32_t pid); bool IsProcessTracked(uint32_t pid) const; @@ -65,8 +63,9 @@ class PresentMonSession { // data std::wstring pm_session_name_; - pwr::cpu::CpuTelemetry* cpu_ = nullptr; - PowerTelemetryContainer* telemetry_container_ = nullptr; + std::string cpu_name_{}; + double cpu_power_limit_ = 0.0; + std::vector telemetry_adapters_{}; // Set the initial telemetry period to 16ms static constexpr uint32_t default_gpu_telemetry_period_ms_ = 16; diff --git a/IntelPresentMon/PresentMonService/acts/EnumerateAdapters.h b/IntelPresentMon/PresentMonService/acts/EnumerateAdapters.h index a7de1174..588bd1ce 100644 --- a/IntelPresentMon/PresentMonService/acts/EnumerateAdapters.h +++ b/IntelPresentMon/PresentMonService/acts/EnumerateAdapters.h @@ -46,12 +46,12 @@ namespace pmon::svc::acts Response out; for (auto&& adapter : ctx.pPmon->EnumerateAdapters()) { out.adapters.push_back(Response::Adapter{ - .id = adapter->GetDeviceId(), - .vendor = adapter->GetVendor(), - .name = adapter->GetName(), - .gpuSustainedPowerLimit = adapter->GetSustainedPowerLimit(), - .gpuMemorySize = adapter->GetDedicatedVideoMemory(), - .gpuMemoryMaxBandwidth = adapter->GetVideoMemoryMaxBandwidth(), + .id = adapter.id, + .vendor = adapter.vendor, + .name = adapter.name, + .gpuSustainedPowerLimit = adapter.gpuSustainedPowerLimit, + .gpuMemorySize = adapter.gpuMemorySize, + .gpuMemoryMaxBandwidth = adapter.gpuMemoryMaxBandwidth, }); } pmlog_dbg(std::format("{} adapters enumerated", out.adapters.size())); From 87e4c1368e3330c7029e24fd78c2b965dbd2b413 Mon Sep 17 00:00:00 2001 From: Chili Date: Sun, 15 Mar 2026 12:11:57 +0900 Subject: [PATCH 13/42] LUID restoration for igcl --- .../ControlLib/TelemetryCoordinator.cpp | 109 +++++++++--------- .../ControlLib/TelemetryCoordinator.h | 4 +- .../ControlLib/TelemetryDeviceFingerprint.h | 2 + .../ControlLib/igcl/IgclTelemetryProvider.cpp | 28 +++-- .../ControlLib/igcl/IgclTelemetryProvider.h | 2 +- 5 files changed, 81 insertions(+), 64 deletions(-) diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp index de19a2de..fc0898a1 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp @@ -15,6 +15,7 @@ #include "../Interprocess/source/SystemDeviceId.h" #include "../Interprocess/source/metadata/MetricList.h" #include +#include #include #include #include @@ -43,6 +44,21 @@ namespace pmon::tel return false; } } + + std::string FormatAdapterLuid_(std::span adapterLuid) + { + if (adapterLuid.empty()) { + return ""; + } + + std::string text{}; + text.reserve(adapterLuid.size() * 3u - 1u); + for (size_t i = 0; i < adapterLuid.size(); ++i) { + text += std::format("{:02X}{}", adapterLuid[i], i != 0 ? " " : ""); + } + + return text; + } } TelemetryCoordinator::TelemetryCoordinator() @@ -62,18 +78,13 @@ namespace pmon::tel const auto& logicalDevice = iLogicalDevice->second; CpuInfo cpuInfo{}; - cpuInfo.name = "UNKNOWN_CPU"; - - bool haveFingerprint = false; - const auto fingerprint = ResolveLogicalDeviceFingerprint_(logicalDevice, haveFingerprint); - if (haveFingerprint) { - cpuInfo.vendor = fingerprint.vendor; - if (!fingerprint.deviceName.empty()) { - cpuInfo.name = fingerprint.deviceName; - } + const auto fingerprint = ResolveLogicalDeviceFingerprint_(logicalDevice); + cpuInfo.vendor = fingerprint.vendor; + if (!fingerprint.deviceName.empty()) { + cpuInfo.name = fingerprint.deviceName; } else { - pmlog_warn("No provider-device fingerprint available for CPU enumeration"); + cpuInfo.name = "UNKNOWN_CPU"; } if (logicalDevice.routes.contains(PM_METRIC_CPU_POWER_LIMIT)) { @@ -108,19 +119,13 @@ namespace pmon::tel AdapterInfo adapter{}; adapter.id = logicalDeviceId; - adapter.name = "UNKNOWN_GPU"; - - bool haveFingerprint = false; - const auto fingerprint = ResolveLogicalDeviceFingerprint_(logicalDevice, haveFingerprint); - if (haveFingerprint) { - adapter.vendor = fingerprint.vendor; - if (!fingerprint.deviceName.empty()) { - adapter.name = fingerprint.deviceName; - } + const auto fingerprint = ResolveLogicalDeviceFingerprint_(logicalDevice); + adapter.vendor = fingerprint.vendor; + if (!fingerprint.deviceName.empty()) { + adapter.name = fingerprint.deviceName; } else { - pmlog_warn("No provider-device fingerprint available for adapter enumeration") - .pmwatch(logicalDeviceId); + adapter.name = "UNKNOWN_GPU"; } const auto populateStaticMetric = [&](PM_METRIC metricId, T& destination) { @@ -166,12 +171,11 @@ namespace pmon::tel bool cpuRegistered = false; for (const auto& [logicalDeviceId, logicalDevice] : logicalDevicesById_) { - bool haveFingerprint = false; - auto fingerprint = ResolveLogicalDeviceFingerprint_(logicalDevice, haveFingerprint); + auto fingerprint = ResolveLogicalDeviceFingerprint_(logicalDevice); auto caps = BuildRoutedCapabilities_(logicalDevice); - const auto vendor = haveFingerprint ? fingerprint.vendor : PM_DEVICE_VENDOR_UNKNOWN; - const auto name = haveFingerprint && !fingerprint.deviceName.empty() ? + const auto vendor = fingerprint.vendor; + const auto name = !fingerprint.deviceName.empty() ? fingerprint.deviceName : std::string{ "UNKNOWN_CPU" }; try { @@ -179,10 +183,10 @@ namespace pmon::tel comms.RegisterGpuDevice( logicalDeviceId, vendor, - haveFingerprint && !fingerprint.deviceName.empty() ? + !fingerprint.deviceName.empty() ? fingerprint.deviceName : std::string{ "UNKNOWN_GPU" }, caps, - std::span{}); + fingerprint.adapterLuid); } else { comms.RegisterCpuDevice(vendor, name, caps); @@ -193,7 +197,6 @@ namespace pmon::tel pmlog_error(util::ReportException("RegisterDevicesToIpc failed for logical device")) .pmwatch(logicalDeviceId) .pmwatch((int)vendor) - .pmwatch(haveFingerprint) .pmwatch(fingerprint.deviceName); } } @@ -209,21 +212,13 @@ namespace pmon::tel const auto requestQpc = util::GetCurrentTimestamp(); // TODO: make static population dynamic by metric id and metadata instead of hardcoded checks. for (const auto& [logicalDeviceId, logicalDevice] : logicalDevicesById_) { - bool haveProviderFingerprint = false; - const auto providerFingerprint = - ResolveLogicalDeviceFingerprint_(logicalDevice, haveProviderFingerprint); + const auto providerFingerprint = ResolveLogicalDeviceFingerprint_(logicalDevice); try { if (logicalDeviceId != ipc::kSystemDeviceId) { auto& store = comms.GetGpuDataStore(logicalDevice.logicalDeviceId); - if (haveProviderFingerprint) { - store.statics.vendor = providerFingerprint.vendor; - store.statics.name = providerFingerprint.deviceName.c_str(); - } - else { - pmlog_warn("No provider-device fingerprint available for GPU static identity") - .pmwatch(logicalDevice.logicalDeviceId); - } + store.statics.vendor = providerFingerprint.vendor; + store.statics.name = providerFingerprint.deviceName.c_str(); if (logicalDevice.routes.contains(PM_METRIC_GPU_SUSTAINED_POWER_LIMIT)) { const auto value = PollMetricForRoute_( @@ -258,14 +253,8 @@ namespace pmon::tel } else { auto& store = comms.GetSystemDataStore(); - if (haveProviderFingerprint) { - store.statics.cpuVendor = providerFingerprint.vendor; - store.statics.cpuName = providerFingerprint.deviceName.c_str(); - } - else { - pmlog_warn("No provider-device fingerprint available for system static identity") - .pmwatch(logicalDevice.logicalDeviceId); - } + store.statics.cpuVendor = providerFingerprint.vendor; + store.statics.cpuName = providerFingerprint.deviceName.c_str(); if (logicalDevice.routes.contains(PM_METRIC_CPU_POWER_LIMIT)) { const auto value = PollMetricForRoute_( @@ -423,6 +412,11 @@ namespace pmon::tel const auto capabilityMap = pProvider->GetCaps(); for (const auto& [providerDeviceId, capabilities] : capabilityMap) { const auto& fingerprint = pProvider->GetFingerPrint(providerDeviceId); + pmlog_dbg("Provider device adapter LUID") + .pmwatch((int)fingerprint.vendor) + .pmwatch(fingerprint.deviceName) + .pmwatch(providerDeviceId) + .pmwatch(FormatAdapterLuid_(fingerprint.adapterLuid)); auto& logicalDevice = GetOrCreateLogicalDevice_(fingerprint); const auto logicalDeviceId = logicalDevice.logicalDeviceId; @@ -580,11 +574,10 @@ namespace pmon::tel } TelemetryDeviceFingerprint TelemetryCoordinator::ResolveLogicalDeviceFingerprint_( - const LogicalDevice_& logicalDevice, - bool& haveFingerprint) const + const LogicalDevice_& logicalDevice) const { TelemetryDeviceFingerprint fingerprint{}; - haveFingerprint = false; + bool haveFingerprint = false; for (const auto& providerDevice : logicalDevice.providerDevices) { const auto pProvider = providerDevice.pProvider.lock(); @@ -602,6 +595,13 @@ namespace pmon::tel haveFingerprint = true; } else { + if (!fingerprint.adapterLuid.empty() && + !providerFingerprint.adapterLuid.empty() && + fingerprint.adapterLuid != providerFingerprint.adapterLuid) { + pmlog_warn("Conflicting provider LUID while resolving logical-device fingerprint") + .pmwatch(logicalDevice.logicalDeviceId) + .pmwatch(providerDevice.providerDeviceId); + } MergeTelemetryDeviceFingerprint(fingerprint, providerFingerprint); } } @@ -612,6 +612,12 @@ namespace pmon::tel } } + if (!haveFingerprint) { + pmlog_error("No provider-device fingerprint resolved for logical device") + .pmwatch(logicalDevice.logicalDeviceId); + throw util::Except<>("No provider-device fingerprint resolved for logical device"); + } + return fingerprint; } @@ -641,10 +647,8 @@ namespace pmon::tel } TelemetryDeviceFingerprint providerFingerprint{}; - bool haveProviderFingerprint = false; try { providerFingerprint = pProvider->GetFingerPrint(providerDevice.providerDeviceId); - haveProviderFingerprint = true; const auto capabilityMap = pProvider->GetCaps(); const auto itDeviceCaps = capabilityMap.find(providerDevice.providerDeviceId); if (itDeviceCaps == capabilityMap.end()) { @@ -675,7 +679,6 @@ namespace pmon::tel .pmwatch(logicalDevice.logicalDeviceId) .pmwatch((int)providerFingerprint.vendor) .pmwatch(providerFingerprint.deviceName) - .pmwatch(haveProviderFingerprint) .pmwatch(providerDevice.providerDeviceId) .pmwatch((int)metricId); } diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.h b/IntelPresentMon/ControlLib/TelemetryCoordinator.h index bf366fec..151672a1 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.h +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.h @@ -74,9 +74,7 @@ namespace pmon::tel void TryCreateConcreteProviders_(); void BuildLogicalDevicesAndRoutes_(); LogicalDevice_& GetOrCreateLogicalDevice_(const TelemetryDeviceFingerprint& fingerprint); - TelemetryDeviceFingerprint ResolveLogicalDeviceFingerprint_( - const LogicalDevice_& logicalDevice, - bool& haveFingerprint) const; + TelemetryDeviceFingerprint ResolveLogicalDeviceFingerprint_(const LogicalDevice_& logicalDevice) const; ipc::MetricCapabilities BuildRoutedCapabilities_(const LogicalDevice_& logicalDevice) const; static void PushValueToTelemetryMap_( ipc::TelemetryMap& telemetryMap, diff --git a/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h b/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h index 0ad74b64..ac77a86f 100644 --- a/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h +++ b/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h @@ -6,6 +6,7 @@ #include #include #include +#include namespace pmon::tel { @@ -15,6 +16,7 @@ namespace pmon::tel PM_DEVICE_VENDOR vendor = PM_DEVICE_VENDOR_UNKNOWN; std::string deviceName; + std::vector adapterLuid; // Correlation fields aligned with NVIDIA matching. std::optional pciDeviceId; std::optional pciSubSystemId; diff --git a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp index fe51e38e..bfa607d9 100644 --- a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp @@ -235,21 +235,32 @@ namespace pmon::tel::igcl device.handle = handle; device.properties = { .Size = sizeof(ctl_device_adapter_properties_t), - .pDeviceID = &device.deviceLuid, - .device_id_size = sizeof(device.deviceLuid), + .pDeviceID = nullptr, + .device_id_size = 0, }; - const auto propertiesResult = ctlGetDeviceProperties(device.handle, &device.properties); + auto propertiesResult = ctlGetDeviceProperties(device.handle, &device.properties); if (propertiesResult != CTL_RESULT_SUCCESS) { - pmlog_error("ctlGetDeviceProperties failed").code(propertiesResult); + pmlog_error("ctlGetDeviceProperties(size query) failed").code(propertiesResult); + return false; + } + + device.deviceLuid.resize((size_t)device.properties.device_id_size); + device.properties = { + .Size = sizeof(ctl_device_adapter_properties_t), + .pDeviceID = device.deviceLuid.empty() ? nullptr : device.deviceLuid.data(), + .device_id_size = (uint32_t)device.deviceLuid.size(), + }; + + propertiesResult = ctlGetDeviceProperties(device.handle, &device.properties); + if (propertiesResult != CTL_RESULT_SUCCESS) { + pmlog_error("ctlGetDeviceProperties(data query) failed").code(propertiesResult); return false; } pmlog_verb(v::tele_gpu)("ctlGetDeviceProperties output") .pmwatch(device.properties.name) .pmwatch(device.providerDeviceId) - .pmwatch(ref::DumpGenerated(device.properties)) - .pmwatch(device.deviceLuid.HighPart) - .pmwatch(device.deviceLuid.LowPart); + .pmwatch(ref::DumpGenerated(device.properties)); if (device.properties.device_type != CTL_DEVICE_TYPE_GRAPHICS) { return false; @@ -258,6 +269,9 @@ namespace pmon::tel::igcl device.fingerprint.deviceType = PM_DEVICE_TYPE_GRAPHICS_ADAPTER; device.fingerprint.vendor = PM_DEVICE_VENDOR_INTEL; device.fingerprint.deviceName = device.properties.name; + if (!device.deviceLuid.empty()) { + device.fingerprint.adapterLuid = device.deviceLuid; + } device.isAlchemist = std::regex_search(device.fingerprint.deviceName, std::regex{ R"(Arc.*A\d{3})" }); pmlog_verb(v::tele_gpu)("Alchemist detection") diff --git a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.h b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.h index 5cb3fad2..b7366ef6 100644 --- a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.h +++ b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.h @@ -58,7 +58,7 @@ namespace pmon::tel::igcl ipc::MetricCapabilities caps{}; ctl_device_adapter_handle_t handle = nullptr; - LUID deviceLuid{}; + std::vector deviceLuid{}; ctl_device_adapter_properties_t properties{}; std::vector memoryModules{}; std::vector powerDomains{}; From e3cae4e03f6a4b673821d315f51af47078371051 Mon Sep 17 00:00:00 2001 From: Chili Date: Sun, 15 Mar 2026 12:47:20 +0900 Subject: [PATCH 14/42] fix nvapi absence reporting and window.h inclusion warnings --- IntelPresentMon/ControlLib/DllModule.h | 3 +-- IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.h | 3 +-- IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.cpp | 1 + IntelPresentMon/ControlLib/nvapi/NvapiWrapper.h | 2 -- IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.cpp | 3 +++ 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/IntelPresentMon/ControlLib/DllModule.h b/IntelPresentMon/ControlLib/DllModule.h index e63b9db4..4d7da013 100644 --- a/IntelPresentMon/ControlLib/DllModule.h +++ b/IntelPresentMon/ControlLib/DllModule.h @@ -1,8 +1,7 @@ // Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: MIT #pragma once -#define NOMINMAX -#include +#include "../CommonUtilities/win/WinAPI.h" #include #include #include diff --git a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.h b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.h index b7366ef6..72d2e8fc 100644 --- a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.h +++ b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.h @@ -1,8 +1,7 @@ // Copyright (C) 2026 Intel Corporation // SPDX-License-Identifier: MIT #pragma once -#define NOMINMAX -#include +#include "../../CommonUtilities/win/WinAPI.h" #include "../EndpointCache.h" #include "../TelemetryProvider.h" diff --git a/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.cpp b/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.cpp index 9e13e712..6edd216c 100644 --- a/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/nvapi/NvapiTelemetryProvider.cpp @@ -1,5 +1,6 @@ // Copyright (C) 2026 Intel Corporation // SPDX-License-Identifier: MIT +#include "../../CommonUtilities/win/WinAPI.h" #include "NvapiTelemetryProvider.h" #include "../Exceptions.h" diff --git a/IntelPresentMon/ControlLib/nvapi/NvapiWrapper.h b/IntelPresentMon/ControlLib/nvapi/NvapiWrapper.h index ad4b2db6..dc262bed 100644 --- a/IntelPresentMon/ControlLib/nvapi/NvapiWrapper.h +++ b/IntelPresentMon/ControlLib/nvapi/NvapiWrapper.h @@ -1,8 +1,6 @@ // Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: MIT #pragma once -#define NOMINMAX -#include #include "../DllModule.h" #include "../MacroHelpers.h" #include "nvapi.h" diff --git a/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.cpp b/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.cpp index 9ce28514..a3e2570c 100644 --- a/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/nvml/NvmlTelemetryProvider.cpp @@ -18,6 +18,9 @@ namespace pmon::tel::nvml try { pNvml_ = std::make_unique(); } + catch (const TelemetrySubsystemAbsent&) { + throw; + } catch (...) { pmlog_error(util::ReportException("NVML wrapper construction failed")); throw Except("Unable to initialize NVIDIA Management Library"); From c8152db07c732fbf4c2c0a51f4e0c3ab37a4e29f Mon Sep 17 00:00:00 2001 From: Chili Date: Sun, 15 Mar 2026 13:16:53 +0900 Subject: [PATCH 15/42] namespace cleanup --- IntelPresentMon/ControlLib/DllModule.h | 60 +++++++++++++------------ IntelPresentMon/ControlLib/Exceptions.h | 9 ++-- IntelPresentMon/ControlLib/Logging.h | 4 +- 3 files changed, 39 insertions(+), 34 deletions(-) diff --git a/IntelPresentMon/ControlLib/DllModule.h b/IntelPresentMon/ControlLib/DllModule.h index 4d7da013..ebe6af57 100644 --- a/IntelPresentMon/ControlLib/DllModule.h +++ b/IntelPresentMon/ControlLib/DllModule.h @@ -9,34 +9,36 @@ #include #include "Exceptions.h" - -class DllModule +namespace pmon::tel { -public: - DllModule(const DllModule& t) = delete; - DllModule& operator=(const DllModule& t) = delete; - DllModule(const std::vector& dllFiles) - { - assert(!dllFiles.empty()); + class DllModule + { + public: + DllModule(const DllModule& t) = delete; + DllModule& operator=(const DllModule& t) = delete; + DllModule(const std::vector& dllFiles) + { + assert(!dllFiles.empty()); - // try list of dll candidates in order - for (const auto& file : dllFiles) { - if (hModule = LoadLibraryExA(file.c_str(), NULL, LOAD_LIBRARY_SEARCH_SYSTEM32)) { - return; - } - } - // if all failed to load, throw exception - auto msg = std::format("Unable to locate telemetry library, last DLL tried: {}", dllFiles.back().c_str()); - throw Except(std::move(msg)); - } - ~DllModule() - { - FreeLibrary(hModule); - } - void* GetProcAddress(const std::string& procName) const - { - return ::GetProcAddress(hModule, procName.c_str()); - } -private: - HMODULE hModule = nullptr; -}; \ No newline at end of file + // try list of dll candidates in order + for (const auto& file : dllFiles) { + if (hModule = LoadLibraryExA(file.c_str(), NULL, LOAD_LIBRARY_SEARCH_SYSTEM32)) { + return; + } + } + // if all failed to load, throw exception + auto msg = std::format("Unable to locate telemetry library, last DLL tried: {}", dllFiles.back().c_str()); + throw Except(std::move(msg)); + } + ~DllModule() + { + FreeLibrary(hModule); + } + void* GetProcAddress(const std::string& procName) const + { + return ::GetProcAddress(hModule, procName.c_str()); + } + private: + HMODULE hModule = nullptr; + }; +} diff --git a/IntelPresentMon/ControlLib/Exceptions.h b/IntelPresentMon/ControlLib/Exceptions.h index fc611875..6c8e4eb9 100644 --- a/IntelPresentMon/ControlLib/Exceptions.h +++ b/IntelPresentMon/ControlLib/Exceptions.h @@ -1,8 +1,11 @@ #pragma once #include "../CommonUtilities/Exception.h" -PM_DEFINE_EX(TelementryException); +namespace pmon::tel +{ + PM_DEFINE_EX(TelementryException); -PM_DEFINE_EX_FROM(TelementryException, TelemetrySubsystemAbsent); + PM_DEFINE_EX_FROM(TelementryException, TelemetrySubsystemAbsent); -using ::pmon::util::Except; \ No newline at end of file + using ::pmon::util::Except; +} diff --git a/IntelPresentMon/ControlLib/Logging.h b/IntelPresentMon/ControlLib/Logging.h index e2d775c7..0dce1470 100644 --- a/IntelPresentMon/ControlLib/Logging.h +++ b/IntelPresentMon/ControlLib/Logging.h @@ -1,4 +1,4 @@ -// Copyright (C) 2022 Intel Corporation +// Copyright (C) 2022 Intel Corporation // SPDX-License-Identifier: MIT #pragma once #include @@ -6,7 +6,7 @@ #include "igcl/igcl_api.h" #include "../CommonUtilities/log/Log.h" -namespace pwr::log +namespace pmon::tel::log { inline std::string MakeErrorLocationString(int line, const char* file, const char* function) { From 778629158615b8ee677f342bb7f77731ce705cd9 Mon Sep 17 00:00:00 2001 From: Chili Date: Sun, 15 Mar 2026 14:13:41 +0900 Subject: [PATCH 16/42] fix luid --- .../ControlLib/TelemetryCoordinator.cpp | 27 +++++-------------- .../ControlLib/TelemetryDeviceFingerprint.cpp | 21 ++++++++++++++- .../ControlLib/TelemetryDeviceFingerprint.h | 4 ++- .../ControlLib/igcl/IgclTelemetryProvider.cpp | 20 +++----------- .../KernelProcess/KernelProcess.args.json | 2 +- 5 files changed, 34 insertions(+), 40 deletions(-) diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp index fc0898a1..202a1119 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp @@ -15,7 +15,6 @@ #include "../Interprocess/source/SystemDeviceId.h" #include "../Interprocess/source/metadata/MetricList.h" #include -#include #include #include #include @@ -45,20 +44,6 @@ namespace pmon::tel } } - std::string FormatAdapterLuid_(std::span adapterLuid) - { - if (adapterLuid.empty()) { - return ""; - } - - std::string text{}; - text.reserve(adapterLuid.size() * 3u - 1u); - for (size_t i = 0; i < adapterLuid.size(); ++i) { - text += std::format("{:02X}{}", adapterLuid[i], i != 0 ? " " : ""); - } - - return text; - } } TelemetryCoordinator::TelemetryCoordinator() @@ -186,7 +171,7 @@ namespace pmon::tel !fingerprint.deviceName.empty() ? fingerprint.deviceName : std::string{ "UNKNOWN_GPU" }, caps, - fingerprint.adapterLuid); + fingerprint.luid); } else { comms.RegisterCpuDevice(vendor, name, caps); @@ -412,11 +397,11 @@ namespace pmon::tel const auto capabilityMap = pProvider->GetCaps(); for (const auto& [providerDeviceId, capabilities] : capabilityMap) { const auto& fingerprint = pProvider->GetFingerPrint(providerDeviceId); - pmlog_dbg("Provider device adapter LUID") + pmlog_dbg("Provider device LUID") .pmwatch((int)fingerprint.vendor) .pmwatch(fingerprint.deviceName) .pmwatch(providerDeviceId) - .pmwatch(FormatAdapterLuid_(fingerprint.adapterLuid)); + .pmwatch(fingerprint.LuidAsString()); auto& logicalDevice = GetOrCreateLogicalDevice_(fingerprint); const auto logicalDeviceId = logicalDevice.logicalDeviceId; @@ -595,9 +580,9 @@ namespace pmon::tel haveFingerprint = true; } else { - if (!fingerprint.adapterLuid.empty() && - !providerFingerprint.adapterLuid.empty() && - fingerprint.adapterLuid != providerFingerprint.adapterLuid) { + if (!fingerprint.luid.empty() && + !providerFingerprint.luid.empty() && + fingerprint.luid != providerFingerprint.luid) { pmlog_warn("Conflicting provider LUID while resolving logical-device fingerprint") .pmwatch(logicalDevice.logicalDeviceId) .pmwatch(providerDevice.providerDeviceId); diff --git a/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.cpp b/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.cpp index a59f3950..b7edde78 100644 --- a/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.cpp +++ b/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.cpp @@ -1,7 +1,8 @@ -// Copyright (C) 2026 Intel Corporation +// Copyright (C) 2026 Intel Corporation // SPDX-License-Identifier: MIT #include "TelemetryDeviceFingerprint.h" #include +#include namespace pmon::tel { @@ -51,6 +52,20 @@ namespace pmon::tel return false; } + std::string TelemetryDeviceFingerprint::LuidAsString() const + { + if (luid.empty()) { + return ""; + } + + std::string text{}; + for (size_t i = 0; i < luid.size(); ++i) { + text += std::format("{}{:02X}", i != 0 ? " " : "", luid[i]); + } + + return text; + } + void MergeTelemetryDeviceFingerprint( TelemetryDeviceFingerprint& dst, const TelemetryDeviceFingerprint& src) @@ -63,6 +78,10 @@ namespace pmon::tel dst.deviceName = src.deviceName; } + if (dst.luid.empty() && !src.luid.empty()) { + dst.luid = src.luid; + } + if (!dst.pciDeviceId.has_value() && src.pciDeviceId.has_value()) { dst.pciDeviceId = src.pciDeviceId; } diff --git a/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h b/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h index ac77a86f..5a0908a4 100644 --- a/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h +++ b/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h @@ -16,11 +16,13 @@ namespace pmon::tel PM_DEVICE_VENDOR vendor = PM_DEVICE_VENDOR_UNKNOWN; std::string deviceName; - std::vector adapterLuid; + std::vector luid; // Correlation fields aligned with NVIDIA matching. std::optional pciDeviceId; std::optional pciSubSystemId; std::optional pciBusId; + + std::string LuidAsString() const; }; bool TelemetryDeviceFingerprintMatches( diff --git a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp index bfa607d9..013172ef 100644 --- a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp @@ -233,28 +233,16 @@ namespace pmon::tel::igcl ctl_device_adapter_handle_t handle) const { device.handle = handle; - device.properties = { - .Size = sizeof(ctl_device_adapter_properties_t), - .pDeviceID = nullptr, - .device_id_size = 0, - }; - - auto propertiesResult = ctlGetDeviceProperties(device.handle, &device.properties); - if (propertiesResult != CTL_RESULT_SUCCESS) { - pmlog_error("ctlGetDeviceProperties(size query) failed").code(propertiesResult); - return false; - } - - device.deviceLuid.resize((size_t)device.properties.device_id_size); + device.deviceLuid.resize(sizeof(LUID)); device.properties = { .Size = sizeof(ctl_device_adapter_properties_t), .pDeviceID = device.deviceLuid.empty() ? nullptr : device.deviceLuid.data(), .device_id_size = (uint32_t)device.deviceLuid.size(), }; - propertiesResult = ctlGetDeviceProperties(device.handle, &device.properties); + const auto propertiesResult = ctlGetDeviceProperties(device.handle, &device.properties); if (propertiesResult != CTL_RESULT_SUCCESS) { - pmlog_error("ctlGetDeviceProperties(data query) failed").code(propertiesResult); + pmlog_error("ctlGetDeviceProperties failed").code(propertiesResult); return false; } pmlog_verb(v::tele_gpu)("ctlGetDeviceProperties output") @@ -270,7 +258,7 @@ namespace pmon::tel::igcl device.fingerprint.vendor = PM_DEVICE_VENDOR_INTEL; device.fingerprint.deviceName = device.properties.name; if (!device.deviceLuid.empty()) { - device.fingerprint.adapterLuid = device.deviceLuid; + device.fingerprint.luid = device.deviceLuid; } device.isAlchemist = std::regex_search(device.fingerprint.deviceName, std::regex{ R"(Arc.*A\d{3})" }); diff --git a/IntelPresentMon/KernelProcess/KernelProcess.args.json b/IntelPresentMon/KernelProcess/KernelProcess.args.json index 46c0098c..28f53e19 100644 --- a/IntelPresentMon/KernelProcess/KernelProcess.args.json +++ b/IntelPresentMon/KernelProcess/KernelProcess.args.json @@ -34,7 +34,7 @@ }, { "Id": "49b6fc1f-b969-4280-b0d8-17a213e80f16", - "Command": "--log-verbose-modules procwatch" + "Command": "--log-verbose-modules tele_gpu" }, { "Id": "bab48d6d-3a48-4b3b-9ed9-903e381824c6", From 8a274cce5734cd9056854f05d50b0a2964c767c2 Mon Sep 17 00:00:00 2001 From: Chili Date: Sun, 15 Mar 2026 15:12:45 +0900 Subject: [PATCH 17/42] dump telemetry caps with pretty metric names --- .../Interprocess/source/MetricCapabilities.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/IntelPresentMon/Interprocess/source/MetricCapabilities.cpp b/IntelPresentMon/Interprocess/source/MetricCapabilities.cpp index bafac4c8..d057814f 100644 --- a/IntelPresentMon/Interprocess/source/MetricCapabilities.cpp +++ b/IntelPresentMon/Interprocess/source/MetricCapabilities.cpp @@ -1,9 +1,24 @@ #include "MetricCapabilities.h" +#include "metadata/MetricList.h" #include #include namespace pmon::ipc { + namespace + { + const char* GetMetricSymbol_(PM_METRIC metricId) noexcept + { + switch (metricId) { +#define X_(id_, ...) case id_: return #id_; + METRIC_LIST(X_) +#undef X_ + default: + return "PM_METRIC_UNKNOWN"; + } + } + } + void MetricCapabilities::Set(PM_METRIC metricId, size_t arraySize) { if (arraySize == 0) { @@ -51,7 +66,8 @@ namespace pmon::ipc oss << indent; } first = false; - oss << "metricId=" << static_cast>(kv.first) + oss << "metric=" << GetMetricSymbol_(kv.first) + << " metricId=" << static_cast>(kv.first) << " arraySize=" << kv.second; } return oss.str(); From e52ee9f97033546c8e8ebe6145984385bda09bd9 Mon Sep 17 00:00:00 2001 From: Chili Date: Sun, 15 Mar 2026 15:42:07 +0900 Subject: [PATCH 18/42] default device discrete --- .../ControlLib/TelemetryCoordinator.cpp | 93 ++++++++++++++++++- .../ControlLib/TelemetryCoordinator.h | 2 + 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp index 202a1119..d1ab2740 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp @@ -93,7 +93,6 @@ namespace pmon::tel std::vector TelemetryCoordinator::EnumerateAdapters() const { - const auto requestQpc = util::GetCurrentTimestamp(); std::vector adapters; adapters.reserve(logicalDevicesById_.size()); @@ -113,7 +112,15 @@ namespace pmon::tel adapter.name = "UNKNOWN_GPU"; } + adapter.gpuMemorySize = QueryGpuMemorySize_(logicalDevice); + const auto requestQpc = util::GetCurrentTimestamp(); const auto populateStaticMetric = [&](PM_METRIC metricId, T& destination) { + if (metricId == PM_METRIC_GPU_MEM_SIZE) { + if constexpr (std::is_same_v) { + destination = adapter.gpuMemorySize; + } + return; + } if (!logicalDevice.routes.contains(metricId)) { return; } @@ -135,7 +142,6 @@ namespace pmon::tel }; populateStaticMetric(PM_METRIC_GPU_SUSTAINED_POWER_LIMIT, adapter.gpuSustainedPowerLimit); - populateStaticMetric(PM_METRIC_GPU_MEM_SIZE, adapter.gpuMemorySize); populateStaticMetric(PM_METRIC_GPU_MEM_MAX_BANDWIDTH, adapter.gpuMemoryMaxBandwidth); adapters.push_back(std::move(adapter)); @@ -506,6 +512,89 @@ namespace pmon::tel } } + ReassignGpuLogicalDeviceIdsByMemorySize_(); + } + + void TelemetryCoordinator::ReassignGpuLogicalDeviceIdsByMemorySize_() + { + struct GpuLogicalDeviceOrdering_ + { + uint32_t oldId = 0; + uint64_t gpuMemorySize = 0; + }; + + std::vector gpuDevices; + gpuDevices.reserve(logicalDevicesById_.size()); + + for (const auto& [logicalDeviceId, logicalDevice] : logicalDevicesById_) { + if (logicalDeviceId == ipc::kSystemDeviceId) { + continue; + } + + gpuDevices.push_back(GpuLogicalDeviceOrdering_{ + .oldId = logicalDeviceId, + .gpuMemorySize = QueryGpuMemorySize_(logicalDevice), + }); + } + + std::sort(gpuDevices.begin(), gpuDevices.end(), [](const GpuLogicalDeviceOrdering_& lhs, const GpuLogicalDeviceOrdering_& rhs) { + if (lhs.gpuMemorySize != rhs.gpuMemorySize) { + return lhs.gpuMemorySize > rhs.gpuMemorySize; + } + return lhs.oldId < rhs.oldId; + }); + + std::unordered_map reorderedLogicalDevices; + reorderedLogicalDevices.reserve(logicalDevicesById_.size()); + + if (const auto itSystem = logicalDevicesById_.find(ipc::kSystemDeviceId); + itSystem != logicalDevicesById_.end()) { + reorderedLogicalDevices.emplace(ipc::kSystemDeviceId, itSystem->second); + } + + uint32_t nextGpuLogicalId = 1; + for (const auto& gpuDevice : gpuDevices) { + auto nh = logicalDevicesById_.extract(gpuDevice.oldId); + if (nh.empty()) { + pmlog_error("Failed extracting logical GPU device during renumber") + .pmwatch(gpuDevice.oldId); + continue; + } + + nh.key() = nextGpuLogicalId; + nh.mapped().logicalDeviceId = nextGpuLogicalId; + reorderedLogicalDevices.insert(std::move(nh)); + ++nextGpuLogicalId; + } + + logicalDevicesById_ = std::move(reorderedLogicalDevices); + nextLogicalDeviceId_ = std::max(nextGpuLogicalId, 1u); + if (nextLogicalDeviceId_ == ipc::kSystemDeviceId) { + ++nextLogicalDeviceId_; + } + } + + uint64_t TelemetryCoordinator::QueryGpuMemorySize_(const LogicalDevice_& logicalDevice) const + { + if (logicalDevice.logicalDeviceId == ipc::kSystemDeviceId || + !logicalDevice.routes.contains(PM_METRIC_GPU_MEM_SIZE)) { + return 0; + } + + try { + const auto value = PollMetricForRoute_( + logicalDevice, PM_METRIC_GPU_MEM_SIZE, 0, util::GetCurrentTimestamp()); + if (const auto pVal = std::get_if(&value)) { + return *pVal; + } + + throw util::Except<>("Type mismatch while querying GPU memory size"); + } + catch (...) { + pmlog_error(util::ReportException("GPU memory size query failed while ordering logical devices")) + .pmwatch(logicalDevice.logicalDeviceId); + return 0; + } } TelemetryCoordinator::LogicalDevice_& TelemetryCoordinator::GetOrCreateLogicalDevice_( diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.h b/IntelPresentMon/ControlLib/TelemetryCoordinator.h index 151672a1..31967bf5 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.h +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.h @@ -73,6 +73,8 @@ namespace pmon::tel // functions void TryCreateConcreteProviders_(); void BuildLogicalDevicesAndRoutes_(); + void ReassignGpuLogicalDeviceIdsByMemorySize_(); + uint64_t QueryGpuMemorySize_(const LogicalDevice_& logicalDevice) const; LogicalDevice_& GetOrCreateLogicalDevice_(const TelemetryDeviceFingerprint& fingerprint); TelemetryDeviceFingerprint ResolveLogicalDeviceFingerprint_(const LogicalDevice_& logicalDevice) const; ipc::MetricCapabilities BuildRoutedCapabilities_(const LogicalDevice_& logicalDevice) const; From 7229c9635ebf14193a367d2cd0ff2835b3fd3d75 Mon Sep 17 00:00:00 2001 From: Chili Date: Sun, 15 Mar 2026 16:56:08 +0900 Subject: [PATCH 19/42] log id decision --- .../ControlLib/TelemetryCoordinator.cpp | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp index d1ab2740..7fdae0ef 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,11 @@ namespace pmon::tel } } + const char* GetDeviceNameOrUnknown_(const TelemetryDeviceFingerprint& fingerprint) noexcept + { + return fingerprint.deviceName.empty() ? "UNKNOWN_GPU" : fingerprint.deviceName.c_str(); + } + } TelemetryCoordinator::TelemetryCoordinator() @@ -561,6 +567,24 @@ namespace pmon::tel continue; } + if (gpuDevice.oldId != nextGpuLogicalId) { + std::string name = "UNKNOWN_GPU"; + try { + const auto fingerprint = ResolveLogicalDeviceFingerprint_(nh.mapped()); + name = GetDeviceNameOrUnknown_(fingerprint); + } + catch (...) { + pmlog_warn(util::ReportException("Failed resolving GPU fingerprint while logging ID reassignment")) + .pmwatch(gpuDevice.oldId) + .pmwatch(nextGpuLogicalId); + } + pmlog_dbg(std::format( + "GPU logical device id reassigned: name=\"{}\" oldId={} newId={} memorySize={}", + name, + gpuDevice.oldId, + nextGpuLogicalId, + gpuDevice.gpuMemorySize)); + } nh.key() = nextGpuLogicalId; nh.mapped().logicalDeviceId = nextGpuLogicalId; reorderedLogicalDevices.insert(std::move(nh)); @@ -572,6 +596,53 @@ namespace pmon::tel if (nextLogicalDeviceId_ == ipc::kSystemDeviceId) { ++nextLogicalDeviceId_; } + + struct FinalGpuOrderEntry_ + { + uint32_t id = 0; + PM_DEVICE_VENDOR vendor = PM_DEVICE_VENDOR_UNKNOWN; + std::string name{}; + uint64_t gpuMemorySize = 0; + }; + + std::vector finalGpuOrder; + finalGpuOrder.reserve(logicalDevicesById_.size()); + + for (const auto& [logicalDeviceId, logicalDevice] : logicalDevicesById_) { + if (logicalDeviceId == ipc::kSystemDeviceId) { + continue; + } + + FinalGpuOrderEntry_ entry{}; + entry.id = logicalDeviceId; + entry.gpuMemorySize = QueryGpuMemorySize_(logicalDevice); + try { + const auto fingerprint = ResolveLogicalDeviceFingerprint_(logicalDevice); + entry.vendor = fingerprint.vendor; + entry.name = GetDeviceNameOrUnknown_(fingerprint); + } + catch (...) { + pmlog_warn(util::ReportException("Failed resolving GPU fingerprint while logging final order")) + .pmwatch(logicalDeviceId); + entry.name = "UNKNOWN_GPU"; + } + finalGpuOrder.push_back(std::move(entry)); + } + + std::sort(finalGpuOrder.begin(), finalGpuOrder.end(), [](const FinalGpuOrderEntry_& lhs, const FinalGpuOrderEntry_& rhs) { + return lhs.id < rhs.id; + }); + + std::ostringstream oss; + oss << "Final GPU logical device ordering:"; + for (size_t i = 0; i < finalGpuOrder.size(); ++i) { + const auto& entry = finalGpuOrder[i]; + oss << "\n" << entry.name; + oss << "\n id: " << entry.id; + oss << "\n vendor: " << (int)entry.vendor; + oss << "\n memorySize: " << entry.gpuMemorySize; + } + pmlog_dbg(oss.str()); } uint64_t TelemetryCoordinator::QueryGpuMemorySize_(const LogicalDevice_& logicalDevice) const From 7974ea5565d24e1e37a723fda59c41b4d11063be Mon Sep 17 00:00:00 2001 From: Chili Date: Sun, 15 Mar 2026 18:00:53 +0900 Subject: [PATCH 20/42] advanced adapter ordering --- .../ControlLib/TelemetryCoordinator.cpp | 111 +++++++++++++++--- .../ControlLib/TelemetryCoordinator.h | 13 +- .../ControlLib/TelemetryDeviceFingerprint.cpp | 16 ++- .../ControlLib/TelemetryDeviceFingerprint.h | 1 + .../ControlLib/igcl/IgclTelemetryProvider.cpp | 2 + 5 files changed, 121 insertions(+), 22 deletions(-) diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp index 7fdae0ef..e467d83b 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp @@ -118,7 +118,7 @@ namespace pmon::tel adapter.name = "UNKNOWN_GPU"; } - adapter.gpuMemorySize = QueryGpuMemorySize_(logicalDevice); + adapter.gpuMemorySize = QueryGpuMemorySize_(logicalDevice).value; const auto requestQpc = util::GetCurrentTimestamp(); const auto populateStaticMetric = [&](PM_METRIC metricId, T& destination) { if (metricId == PM_METRIC_GPU_MEM_SIZE) { @@ -526,6 +526,11 @@ namespace pmon::tel struct GpuLogicalDeviceOrdering_ { uint32_t oldId = 0; + std::string name{}; + bool isIntegratedAdapter = false; + bool hasSustainedPowerLimit = false; + double sustainedPowerLimit = 0.0; + bool hasMemorySize = false; uint64_t gpuMemorySize = 0; }; @@ -536,19 +541,46 @@ namespace pmon::tel if (logicalDeviceId == ipc::kSystemDeviceId) { continue; } + const auto fingerprint = ResolveLogicalDeviceFingerprint_(logicalDevice); + const auto powerInfo = QueryGpuSustainedPowerLimit_(logicalDevice); + const auto memInfo = QueryGpuMemorySize_(logicalDevice); gpuDevices.push_back(GpuLogicalDeviceOrdering_{ .oldId = logicalDeviceId, - .gpuMemorySize = QueryGpuMemorySize_(logicalDevice), + .name = GetDeviceNameOrUnknown_(fingerprint), + .isIntegratedAdapter = fingerprint.isIntegratedAdapter, + .hasSustainedPowerLimit = powerInfo.hasValue, + .sustainedPowerLimit = powerInfo.value, + .hasMemorySize = memInfo.hasValue, + .gpuMemorySize = memInfo.value, }); } - std::sort(gpuDevices.begin(), gpuDevices.end(), [](const GpuLogicalDeviceOrdering_& lhs, const GpuLogicalDeviceOrdering_& rhs) { - if (lhs.gpuMemorySize != rhs.gpuMemorySize) { - return lhs.gpuMemorySize > rhs.gpuMemorySize; - } - return lhs.oldId < rhs.oldId; - }); + const bool allHaveSustainedPowerLimit = !gpuDevices.empty() && + std::ranges::all_of(gpuDevices, [](const GpuLogicalDeviceOrdering_& gpuDevice) { + return gpuDevice.hasSustainedPowerLimit; + }); + + std::sort(gpuDevices.begin(), gpuDevices.end(), + [allHaveSustainedPowerLimit](const GpuLogicalDeviceOrdering_& lhs, const GpuLogicalDeviceOrdering_& rhs) { + if (lhs.isIntegratedAdapter != rhs.isIntegratedAdapter) { + return rhs.isIntegratedAdapter; + } + if (allHaveSustainedPowerLimit) { + if (lhs.sustainedPowerLimit != rhs.sustainedPowerLimit) { + return lhs.sustainedPowerLimit > rhs.sustainedPowerLimit; + } + } + else { + if (lhs.hasMemorySize != rhs.hasMemorySize) { + return lhs.hasMemorySize > rhs.hasMemorySize; + } + if (lhs.gpuMemorySize != rhs.gpuMemorySize) { + return lhs.gpuMemorySize > rhs.gpuMemorySize; + } + } + return lhs.oldId < rhs.oldId; + }); std::unordered_map reorderedLogicalDevices; reorderedLogicalDevices.reserve(logicalDevicesById_.size()); @@ -579,11 +611,16 @@ namespace pmon::tel .pmwatch(nextGpuLogicalId); } pmlog_dbg(std::format( - "GPU logical device id reassigned: name=\"{}\" oldId={} newId={} memorySize={}", + "GPU logical device id reassigned: name=\"{}\" oldId={} newId={} integrated={} sustainedPowerLimit={} hasSustainedPowerLimit={} memorySize={} hasMemorySize={} rankingBasis={}", name, gpuDevice.oldId, nextGpuLogicalId, - gpuDevice.gpuMemorySize)); + gpuDevice.isIntegratedAdapter, + gpuDevice.sustainedPowerLimit, + gpuDevice.hasSustainedPowerLimit, + gpuDevice.gpuMemorySize, + gpuDevice.hasMemorySize, + allHaveSustainedPowerLimit ? "sustainedPower" : "memory")); } nh.key() = nextGpuLogicalId; nh.mapped().logicalDeviceId = nextGpuLogicalId; @@ -602,6 +639,10 @@ namespace pmon::tel uint32_t id = 0; PM_DEVICE_VENDOR vendor = PM_DEVICE_VENDOR_UNKNOWN; std::string name{}; + bool isIntegratedAdapter = false; + bool hasSustainedPowerLimit = false; + double sustainedPowerLimit = 0.0; + bool hasMemorySize = false; uint64_t gpuMemorySize = 0; }; @@ -615,11 +656,17 @@ namespace pmon::tel FinalGpuOrderEntry_ entry{}; entry.id = logicalDeviceId; - entry.gpuMemorySize = QueryGpuMemorySize_(logicalDevice); + const auto powerInfo = QueryGpuSustainedPowerLimit_(logicalDevice); + const auto memInfo = QueryGpuMemorySize_(logicalDevice); + entry.hasSustainedPowerLimit = powerInfo.hasValue; + entry.sustainedPowerLimit = powerInfo.value; + entry.hasMemorySize = memInfo.hasValue; + entry.gpuMemorySize = memInfo.value; try { const auto fingerprint = ResolveLogicalDeviceFingerprint_(logicalDevice); entry.vendor = fingerprint.vendor; entry.name = GetDeviceNameOrUnknown_(fingerprint); + entry.isIntegratedAdapter = fingerprint.isIntegratedAdapter; } catch (...) { pmlog_warn(util::ReportException("Failed resolving GPU fingerprint while logging final order")) @@ -635,28 +682,36 @@ namespace pmon::tel std::ostringstream oss; oss << "Final GPU logical device ordering:"; + oss << "\n rankingBasis: " << (allHaveSustainedPowerLimit ? "sustainedPower" : "memory"); for (size_t i = 0; i < finalGpuOrder.size(); ++i) { const auto& entry = finalGpuOrder[i]; oss << "\n" << entry.name; oss << "\n id: " << entry.id; oss << "\n vendor: " << (int)entry.vendor; + oss << "\n integrated: " << entry.isIntegratedAdapter; + oss << "\n hasSustainedPowerLimit: " << entry.hasSustainedPowerLimit; + oss << "\n sustainedPowerLimit: " << entry.sustainedPowerLimit; + oss << "\n hasMemorySize: " << entry.hasMemorySize; oss << "\n memorySize: " << entry.gpuMemorySize; } pmlog_dbg(oss.str()); } - uint64_t TelemetryCoordinator::QueryGpuMemorySize_(const LogicalDevice_& logicalDevice) const + TelemetryCoordinator::GpuMemoryOrderingInfo_ TelemetryCoordinator::QueryGpuMemorySize_(const LogicalDevice_& logicalDevice) const { + GpuMemoryOrderingInfo_ out{}; if (logicalDevice.logicalDeviceId == ipc::kSystemDeviceId || !logicalDevice.routes.contains(PM_METRIC_GPU_MEM_SIZE)) { - return 0; + return out; } try { const auto value = PollMetricForRoute_( logicalDevice, PM_METRIC_GPU_MEM_SIZE, 0, util::GetCurrentTimestamp()); if (const auto pVal = std::get_if(&value)) { - return *pVal; + out.hasValue = true; + out.value = *pVal; + return out; } throw util::Except<>("Type mismatch while querying GPU memory size"); @@ -664,7 +719,33 @@ namespace pmon::tel catch (...) { pmlog_error(util::ReportException("GPU memory size query failed while ordering logical devices")) .pmwatch(logicalDevice.logicalDeviceId); - return 0; + return out; + } + } + + TelemetryCoordinator::GpuPowerOrderingInfo_ TelemetryCoordinator::QueryGpuSustainedPowerLimit_(const LogicalDevice_& logicalDevice) const + { + GpuPowerOrderingInfo_ out{}; + if (logicalDevice.logicalDeviceId == ipc::kSystemDeviceId || + !logicalDevice.routes.contains(PM_METRIC_GPU_SUSTAINED_POWER_LIMIT)) { + return out; + } + + try { + const auto value = PollMetricForRoute_( + logicalDevice, PM_METRIC_GPU_SUSTAINED_POWER_LIMIT, 0, util::GetCurrentTimestamp()); + if (const auto pVal = std::get_if(&value)) { + out.hasValue = true; + out.value = *pVal; + return out; + } + + throw util::Except<>("Type mismatch while querying GPU sustained power limit"); + } + catch (...) { + pmlog_error(util::ReportException("GPU sustained power limit query failed while ordering logical devices")) + .pmwatch(logicalDevice.logicalDeviceId); + return out; } } diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.h b/IntelPresentMon/ControlLib/TelemetryCoordinator.h index 31967bf5..10ae5b8e 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.h +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.h @@ -70,11 +70,22 @@ namespace pmon::tel // maps metrics to an index into providerDevices std::unordered_map routes; }; + struct GpuMemoryOrderingInfo_ + { + bool hasValue = false; + uint64_t value = 0; + }; + struct GpuPowerOrderingInfo_ + { + bool hasValue = false; + double value = 0.0; + }; // functions void TryCreateConcreteProviders_(); void BuildLogicalDevicesAndRoutes_(); void ReassignGpuLogicalDeviceIdsByMemorySize_(); - uint64_t QueryGpuMemorySize_(const LogicalDevice_& logicalDevice) const; + GpuMemoryOrderingInfo_ QueryGpuMemorySize_(const LogicalDevice_& logicalDevice) const; + GpuPowerOrderingInfo_ QueryGpuSustainedPowerLimit_(const LogicalDevice_& logicalDevice) const; LogicalDevice_& GetOrCreateLogicalDevice_(const TelemetryDeviceFingerprint& fingerprint); TelemetryDeviceFingerprint ResolveLogicalDeviceFingerprint_(const LogicalDevice_& logicalDevice) const; ipc::MetricCapabilities BuildRoutedCapabilities_(const LogicalDevice_& logicalDevice) const; diff --git a/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.cpp b/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.cpp index b7edde78..597e7eba 100644 --- a/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.cpp +++ b/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.cpp @@ -70,27 +70,31 @@ namespace pmon::tel TelemetryDeviceFingerprint& dst, const TelemetryDeviceFingerprint& src) { - if (dst.vendor == PM_DEVICE_VENDOR_UNKNOWN && src.vendor != PM_DEVICE_VENDOR_UNKNOWN) { + if (dst.vendor == PM_DEVICE_VENDOR_UNKNOWN) { dst.vendor = src.vendor; } - if (dst.deviceName.empty() && !src.deviceName.empty()) { + if (dst.deviceName.empty()) { dst.deviceName = src.deviceName; } - if (dst.luid.empty() && !src.luid.empty()) { + if (!dst.isIntegratedAdapter) { + dst.isIntegratedAdapter = src.isIntegratedAdapter; + } + + if (dst.luid.empty()) { dst.luid = src.luid; } - if (!dst.pciDeviceId.has_value() && src.pciDeviceId.has_value()) { + if (!dst.pciDeviceId.has_value()) { dst.pciDeviceId = src.pciDeviceId; } - if (!dst.pciSubSystemId.has_value() && src.pciSubSystemId.has_value()) { + if (!dst.pciSubSystemId.has_value()) { dst.pciSubSystemId = src.pciSubSystemId; } - if (!dst.pciBusId.has_value() && src.pciBusId.has_value()) { + if (!dst.pciBusId.has_value()) { dst.pciBusId = src.pciBusId; } } diff --git a/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h b/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h index 5a0908a4..cd779c1c 100644 --- a/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h +++ b/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.h @@ -15,6 +15,7 @@ namespace pmon::tel PM_DEVICE_TYPE deviceType = PM_DEVICE_TYPE_INDEPENDENT; PM_DEVICE_VENDOR vendor = PM_DEVICE_VENDOR_UNKNOWN; std::string deviceName; + bool isIntegratedAdapter = false; std::vector luid; // Correlation fields aligned with NVIDIA matching. diff --git a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp index 013172ef..1e1df0a0 100644 --- a/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/igcl/IgclTelemetryProvider.cpp @@ -257,6 +257,8 @@ namespace pmon::tel::igcl device.fingerprint.deviceType = PM_DEVICE_TYPE_GRAPHICS_ADAPTER; device.fingerprint.vendor = PM_DEVICE_VENDOR_INTEL; device.fingerprint.deviceName = device.properties.name; + device.fingerprint.isIntegratedAdapter = + (device.properties.graphics_adapter_properties & CTL_ADAPTER_PROPERTIES_FLAG_INTEGRATED) != 0; if (!device.deviceLuid.empty()) { device.fingerprint.luid = device.deviceLuid; } From b106ecdaf6c302f440bd8bff56889b013f1ab952 Mon Sep 17 00:00:00 2001 From: Chili Date: Sun, 15 Mar 2026 18:20:06 +0900 Subject: [PATCH 21/42] simple default device --- .../Core/source/pmon/PresentMon.cpp | 28 +------------------ 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/IntelPresentMon/Core/source/pmon/PresentMon.cpp b/IntelPresentMon/Core/source/pmon/PresentMon.cpp index 6f67ac44..00b93b7c 100644 --- a/IntelPresentMon/Core/source/pmon/PresentMon.cpp +++ b/IntelPresentMon/Core/source/pmon/PresentMon.cpp @@ -145,42 +145,16 @@ namespace p2c::pmon { const auto& intro = *pIntrospectionRoot; uint32_t bestId = 0; - uint64_t bestMem = 0; for (const auto& device : intro.GetDevices()) { if (device.GetType() != PM_DEVICE_TYPE_GRAPHICS_ADAPTER) { continue; } - uint64_t memSize = 0; - bool hasValue = false; - try { - memSize = pmapi::PollStatic(*pSession, - PM_METRIC_GPU_MEM_SIZE, device.GetId(), 0).As(); - hasValue = true; - } - catch (...) { - hasValue = false; - } - - if (hasValue) { - if (memSize > bestMem) { - bestMem = memSize; - bestId = device.GetId(); - } - } - else if (bestId == 0) { + if (bestId == 0 || device.GetId() < bestId) { bestId = device.GetId(); } } - if (bestId == 0) { - for (const auto& device : intro.GetDevices()) { - if (device.GetType() == PM_DEVICE_TYPE_GRAPHICS_ADAPTER) { - return device.GetId(); - } - } - } - return bestId; } } From 9b95f426ddc12d4383d40e0b9ce321818e30b3b2 Mon Sep 17 00:00:00 2001 From: "Taylor, Raymond" Date: Mon, 16 Mar 2026 09:58:55 +0900 Subject: [PATCH 22/42] uci provider working uci first draft uci verbose uci wix install fix uci parsing cleanup --- IntelPresentMon/CommonUtilities/log/Verbose.h | 1 + IntelPresentMon/ControlLib/ControlLib.vcxproj | 10 +- .../ControlLib/ControlLib.vcxproj.filters | 9 + .../ControlLib/TelemetryCoordinator.cpp | 42 +- .../ControlLib/TelemetryCoordinator.h | 7 +- .../ControlLib/TelemetryDeviceFingerprint.cpp | 14 +- .../ControlLib/TelemetryProvider.h | 9 + IntelPresentMon/ControlLib/Ver.h | 24 - IntelPresentMon/ControlLib/ipf_sdk_version.h | 50 -- IntelPresentMon/ControlLib/ipf_version.h | 35 - IntelPresentMon/ControlLib/uci/.gitignore | 1 + .../ControlLib/uci/UciTelemetryProvider.cpp | 670 ++++++++++++++++++ .../ControlLib/uci/UciTelemetryProvider.h | 81 +++ .../Interprocess/source/metadata/MetricList.h | 2 +- IntelPresentMon/PMInstallerLib/Library.wxs | 1 + .../PMInstallerLib/PMInstallerLib.wixproj | 7 +- IntelPresentMon/PMInstallerLib/UciDist.wxs | 166 +++++ .../PMInstallerLib/wix-uci-dist.ps1 | 92 +++ .../PresentMonService/PMMainThread.cpp | 9 +- IntelPresentMon/metrics.csv | 6 +- Tools/generate/EnumMetric/metrics.awk | 2 + 21 files changed, 1109 insertions(+), 129 deletions(-) delete mode 100644 IntelPresentMon/ControlLib/Ver.h delete mode 100644 IntelPresentMon/ControlLib/ipf_sdk_version.h delete mode 100644 IntelPresentMon/ControlLib/ipf_version.h create mode 100644 IntelPresentMon/ControlLib/uci/.gitignore create mode 100644 IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp create mode 100644 IntelPresentMon/ControlLib/uci/UciTelemetryProvider.h create mode 100644 IntelPresentMon/PMInstallerLib/UciDist.wxs create mode 100644 IntelPresentMon/PMInstallerLib/wix-uci-dist.ps1 diff --git a/IntelPresentMon/CommonUtilities/log/Verbose.h b/IntelPresentMon/CommonUtilities/log/Verbose.h index 8e598bcf..3c7c8f2b 100644 --- a/IntelPresentMon/CommonUtilities/log/Verbose.h +++ b/IntelPresentMon/CommonUtilities/log/Verbose.h @@ -9,6 +9,7 @@ namespace pmon::util::log v8async, procwatch, tele_gpu, + uci, core_metric, core_hotkey, core_window, diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj b/IntelPresentMon/ControlLib/ControlLib.vcxproj index a67a324a..f86c1728 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj @@ -73,13 +73,14 @@ MultiThreadedDebug stdcpplatest true + uci\inc;%(AdditionalIncludeDirectories) Console true - wbemuuid.lib;%(AdditionalDependencies) + wbemuuid.lib;unified-collector-interface.lib;%(AdditionalDependencies) @@ -95,6 +96,7 @@ true NDEBUG;%(PreprocessorDefinitions) Guard + uci\inc;%(AdditionalIncludeDirectories) Console @@ -103,7 +105,7 @@ true - wbemuuid.lib;%(AdditionalDependencies) + wbemuuid.lib;unified-collector-interface.lib;%(AdditionalDependencies) @@ -130,6 +132,7 @@ + @@ -144,6 +147,7 @@ + @@ -157,4 +161,4 @@ - + \ No newline at end of file diff --git a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters index 62b6c898..9d2c31ae 100644 --- a/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters +++ b/IntelPresentMon/ControlLib/ControlLib.vcxproj.filters @@ -17,6 +17,9 @@ {a6df2cb9-9e2a-46e5-8adb-ff8f258e2a36} + + {6db4e810-a194-46a6-ac19-44e86c4b2645} + @@ -79,6 +82,9 @@ Wmi + + Uci + @@ -113,5 +119,8 @@ Wmi + + Uci + diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp index e467d83b..c7d57f96 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp @@ -8,6 +8,7 @@ #include "igcl/IgclTelemetryProvider.h" #include "nvapi/NvapiTelemetryProvider.h" #include "nvml/NvmlTelemetryProvider.h" +#include "uci/UciTelemetryProvider.h" #include "wmi/WmiTelemetryProvider.h" #include "../CommonUtilities/Exception.h" #include "../CommonUtilities/Qpc.h" @@ -52,7 +53,9 @@ namespace pmon::tel } - TelemetryCoordinator::TelemetryCoordinator() + TelemetryCoordinator::TelemetryCoordinator(uint32_t pollRateMs) + : + pollRateMs_{ std::max(pollRateMs, 1u) } { TryCreateConcreteProviders_(); BuildLogicalDevicesAndRoutes_(); @@ -290,6 +293,31 @@ namespace pmon::tel return availability; } + void TelemetryCoordinator::SetPollRate(uint32_t pollRateMs) + { + pollRateMs_ = std::max(pollRateMs, 1u); + for (const auto& pProvider : providerPtrs_) { + try { + pProvider->SetPollRate(pollRateMs_); + } + catch (...) { + pmlog_error(util::ReportException("Telemetry provider poll-rate update failed")); + } + } + } + + void TelemetryCoordinator::SetMetricUse(const svc::DeviceMetricUse& metricUse) + { + for (const auto& pProvider : providerPtrs_) { + try { + pProvider->SetMetricUse(metricUse); + } + catch (...) { + pmlog_error(util::ReportException("Telemetry provider metric-use update failed")); + } + } + } + size_t TelemetryCoordinator::PollToIpc( const svc::DeviceMetricUse& metricUse, ipc::ServiceComms& comms) const @@ -364,7 +392,9 @@ namespace pmon::tel const auto tryAddProvider = [this](const char* missingMessage, const char* failureMessage) { try { - providerPtrs_.push_back(std::make_shared()); + auto pProvider = std::make_shared(); + pProvider->SetPollRate(pollRateMs_); + providerPtrs_.push_back(std::move(pProvider)); } catch (const TelemetrySubsystemAbsent&) { pmlog_dbg(util::ReportException(missingMessage)); @@ -377,6 +407,9 @@ namespace pmon::tel tryAddProvider.operator()( "WMI telemetry provider unavailable", "WMI telemetry provider construction failed"); + tryAddProvider.operator()( + "UCI telemetry provider unavailable", + "UCI telemetry provider construction failed"); tryAddProvider.operator()( "ADL telemetry provider unavailable", "ADL telemetry provider construction failed"); @@ -400,11 +433,6 @@ namespace pmon::tel std::unordered_map routeCandidatesByLogicalId; for (const auto& pProvider : providerPtrs_) { - if (!pProvider) { - pmlog_error("Null pointer in provider ptrs"); - continue; - } - try { const auto capabilityMap = pProvider->GetCaps(); for (const auto& [providerDeviceId, capabilities] : capabilityMap) { diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.h b/IntelPresentMon/ControlLib/TelemetryCoordinator.h index 10ae5b8e..cdab4362 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.h +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.h @@ -40,7 +40,7 @@ namespace pmon::tel // Constructs all known concrete providers, correlates logical devices, // and builds metric polling routes. - TelemetryCoordinator(); + explicit TelemetryCoordinator(uint32_t pollRateMs); // Returns system CPU static identity and routed static telemetry when present. std::optional GetCpuInfo() const; // Returns GPU adapter identity and routed static telemetry for legacy service enumeration. @@ -51,6 +51,10 @@ namespace pmon::tel void PopulateStaticsToIpc(ipc::ServiceComms& comms) const; // Returns aggregate availability across all routed logical devices. ipc::MetricCapabilities GetAvailability() const; + // Broadcasts requested active telemetry polling cadence to providers that need it. + void SetPollRate(uint32_t pollRateMs); + // Broadcasts current routed metric interest to providers that need active configuration. + void SetMetricUse(const svc::DeviceMetricUse& metricUse); // Polls routed telemetry metrics and pushes samples directly to IPC rings. size_t PollToIpc( const svc::DeviceMetricUse& metricUse, @@ -104,5 +108,6 @@ namespace pmon::tel std::vector> providerPtrs_; std::unordered_map logicalDevicesById_; uint32_t nextLogicalDeviceId_ = 1; + uint32_t pollRateMs_ = 1000; }; } diff --git a/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.cpp b/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.cpp index 597e7eba..1a5a9d81 100644 --- a/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.cpp +++ b/IntelPresentMon/ControlLib/TelemetryDeviceFingerprint.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2026 Intel Corporation +// Copyright (C) 2026 Intel Corporation // SPDX-License-Identifier: MIT #include "TelemetryDeviceFingerprint.h" #include @@ -32,7 +32,17 @@ namespace pmon::tel const TelemetryDeviceFingerprint& lhs, const TelemetryDeviceFingerprint& rhs) noexcept { - if (lhs.deviceType != rhs.deviceType || lhs.vendor != rhs.vendor) { + if (lhs.deviceType != rhs.deviceType) { + return false; + } + + // There is only one logical system device exposed through IPC. Any + // provider reporting PM_DEVICE_TYPE_SYSTEM should correlate to it. + if (lhs.deviceType == PM_DEVICE_TYPE_SYSTEM) { + return true; + } + + if (lhs.vendor != rhs.vendor) { return false; } diff --git a/IntelPresentMon/ControlLib/TelemetryProvider.h b/IntelPresentMon/ControlLib/TelemetryProvider.h index 1d2e9310..ee9b87cd 100644 --- a/IntelPresentMon/ControlLib/TelemetryProvider.h +++ b/IntelPresentMon/ControlLib/TelemetryProvider.h @@ -3,6 +3,7 @@ #pragma once #include "TelemetryDeviceFingerprint.h" +#include "../PresentMonService/MetricUse.h" #include "../Interprocess/source/MetricCapabilities.h" #include "../Interprocess/source/TelemetryMap.h" #include @@ -26,5 +27,13 @@ namespace pmon::tel PM_METRIC metricId, uint32_t arrayIndex, int64_t requestQpc) = 0; + virtual void SetPollRate(uint32_t pollRateMs) + { + (void)pollRateMs; + } + virtual void SetMetricUse(const svc::DeviceMetricUse& metricUse) + { + (void)metricUse; + } }; } diff --git a/IntelPresentMon/ControlLib/Ver.h b/IntelPresentMon/ControlLib/Ver.h deleted file mode 100644 index 7ec0b69f..00000000 --- a/IntelPresentMon/ControlLib/Ver.h +++ /dev/null @@ -1,24 +0,0 @@ -/****************************************************************************** -** Copyright (c) 2013-2022 Intel Corporation All Rights Reserved -** -** Licensed under the Apache License, Version 2.0 (the "License"); you may not -** use this file except in compliance with the License. -** -** You may obtain a copy of the License at -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -** WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** -** See the License for the specific language governing permissions and -** limitations under the License. -** -******************************************************************************/ - -#pragma once - -#define VER_MAJOR 1 -#define VER_MINOR 0 -#define VER_HOTFIX 11101 -#define VER_BUILD 30068 diff --git a/IntelPresentMon/ControlLib/ipf_sdk_version.h b/IntelPresentMon/ControlLib/ipf_sdk_version.h deleted file mode 100644 index cc966e49..00000000 --- a/IntelPresentMon/ControlLib/ipf_sdk_version.h +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************** -** Copyright (c) 2013-2022 Intel Corporation All Rights Reserved -** -** Licensed under the Apache License, Version 2.0 (the "License"); you may not -** use this file except in compliance with the License. -** -** You may obtain a copy of the License at -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -** WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** -** See the License for the specific language governing permissions and -** limitations under the License. -** -******************************************************************************/ - -#pragma once - -#include "esif_ccb.h" -#include "esif_ccb_rc.h" -#include -#include - -// Current IPF SDK Version: Major.Minor.Revision where same Major.Minor compatible with other Revisions, but not newer Major.Minor -#define IPF_SDK_VERSION "1.0.11100" - -typedef u64 ipfsdk_version_t; // IPF SDK Encoded Version Number - -// IPF SDK Encoded Version Number Helper Macros -#define IPFSDK_VERSION(major, minor, revision) ((((ipfsdk_version_t)(major) & 0xffff) << 32) | (((ipfsdk_version_t)(minor) & 0xffff) << 16) | ((ipfsdk_version_t)(revision) & 0xffff)) -#define IPFSDK_GETMAJOR(ver) ((u32)(((ver) & 0x0000ffff00000000) >> 32)) -#define IPFSDK_GETMINOR(ver) (((u32)(ver) & 0xffff0000) >> 16) -#define IPFSDK_GETRELEASE(ver) ((u32)(((ver) & 0x0000ffffffff0000) >> 16)) -#define IPFSDK_GETREVISION(ver) ((u32)(ver) & 0x0000ffff) - -// Convert an IPF SDK Version string to an Encoded Version Number that can be directly compared with another -static ESIF_INLINE ipfsdk_version_t IpfSdk_VersionFromString(const char *str) { - ipfsdk_version_t ver = 0; - if (str) { - const char *dot = strchr(str, '.'); - const char *dotdot = (dot ? strchr(dot + 1, '.') : NULL); - u32 major = atoi(str); - u32 minor = (dot ? atoi(dot + 1) : 0); - u32 revision = (dotdot ? atoi(dotdot + 1) : 0); - ver = IPFSDK_VERSION(major, minor, revision); - } - return ver; -} diff --git a/IntelPresentMon/ControlLib/ipf_version.h b/IntelPresentMon/ControlLib/ipf_version.h deleted file mode 100644 index 08d4d02b..00000000 --- a/IntelPresentMon/ControlLib/ipf_version.h +++ /dev/null @@ -1,35 +0,0 @@ -/****************************************************************************** -** Copyright (c) 2013-2022 Intel Corporation All Rights Reserved -** -** Licensed under the Apache License, Version 2.0 (the "License"); you may not -** use this file except in compliance with the License. -** -** You may obtain a copy of the License at -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -** WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** -** See the License for the specific language governing permissions and -** limitations under the License. -** -******************************************************************************/ - -#pragma once - -#include "Ver.h" - -#define STR(arg) #arg -#define STR2(arg) STR(##arg) -#define EXPAND_TOSTR(arg) STR(arg) - -// -// TODO: Modify to set version during build process via automation -// -#define IPF_VER_MAJOR VER_MAJOR -#define IPF_VER_MINOR VER_MINOR -#define IPF_VER_HOTFIX VER_HOTFIX -#define IPF_VER_BUILD VER_BUILD - -#define IPF_APP_VERSION EXPAND_TOSTR(IPF_VER_MAJOR.IPF_VER_MINOR.IPF_VER_HOTFIX.IPF_VER_BUILD) diff --git a/IntelPresentMon/ControlLib/uci/.gitignore b/IntelPresentMon/ControlLib/uci/.gitignore new file mode 100644 index 00000000..77738287 --- /dev/null +++ b/IntelPresentMon/ControlLib/uci/.gitignore @@ -0,0 +1 @@ +dist/ \ No newline at end of file diff --git a/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp b/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp new file mode 100644 index 00000000..d069f40c --- /dev/null +++ b/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp @@ -0,0 +1,670 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#include "UciTelemetryProvider.h" + +#include "../Exceptions.h" +#include "../Logging.h" +#include "../../CommonUtilities/Exception.h" +#include "../../CommonUtilities/log/GlobalPolicy.h" +#include "../../CommonUtilities/str/String.h" + +#include "inc/uci/uci-versions.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace pmon; + +namespace pmon::tel::uci +{ + namespace + { + using v = util::log::V; + + constexpr std::string_view kCpuPowerMetricName_ = "pkg-pwr"; + constexpr std::string_view kCpuTemperatureMetricName_ = "core-temp"; + constexpr std::string_view kCpuPowerRecordMetricName_ = "PKG-PWR"; + constexpr std::string_view kCpuTemperatureRecordMetricName_ = "TEMP"; + constexpr std::string_view kCoreEntityPrefix_ = "Core_"; + + struct MetricContainerGuard_ + { + uciMetricContainerHandle handle = nullptr; + + ~MetricContainerGuard_() + { + if (handle != nullptr) { + uciFreeMetricContainer(handle); + } + } + }; + + [[noreturn]] void ThrowUciError_(uc_result_t result, const char* call, bool subsystemAbsent) + { + const auto message = std::format("UCI call [{}] failed with code [{}]", call, (int)result); + if (subsystemAbsent) { + throw Except(message); + } + throw Except<>(message); + } + + void CheckUciCall_(uc_result_t result, const char* call, bool subsystemAbsent = false) + { + if (result != UC_SUCCESS) { + ThrowUciError_(result, call, subsystemAbsent); + } + } + + bool TryGetString_(auto getter, auto handle, std::string& value) + { + char* pText = nullptr; + if (getter(handle, &pText) != UC_SUCCESS || pText == nullptr) { + value.clear(); + return false; + } + value = pText; + return true; + } + + bool TryGetSample_(auto getter, uciMetricRecordHandle record, double& sample) + { + return getter(record, &sample) == UC_SUCCESS; + } + + bool TryGetDuration_(auto getter, uciMetricRecordHandle record, uint64_t& duration) + { + return getter(record, &duration) == UC_SUCCESS; + } + + void DumpDataCallback_(uciDataBundle* dataBundle) + { + std::ostringstream oss; + if (dataBundle == nullptr) { + oss << "UCI callback received null data bundle"; + pmlog_verb(v::uci)(oss.str()); + return; + } + + oss << "UCI callback received numRecords=" << dataBundle->numRecords << '\n'; + if (dataBundle->records == nullptr) { + oss << "records pointer is null"; + pmlog_verb(v::uci)(oss.str()); + return; + } + + for (uint16_t i = 0; i < dataBundle->numRecords; ++i) { + const auto record = dataBundle->records[i]; + oss << "record[" << i << "] handle=" << record << '\n'; + if (record == nullptr) { + continue; + } + + std::string metricName; + std::string entity; + std::string descriptor; + std::string unit; + double sample = 0.0; + uint64_t timestamp = 0; + uint64_t duration = 0; + + if (TryGetString_(uciMetricRecordGetMetricName, record, metricName)) { + oss << "record[" << i << "].metricName=\"" << metricName << "\"\n"; + } + if (TryGetString_(uciMetricRecordGetEntity, record, entity)) { + oss << "record[" << i << "].entity=\"" << entity << "\"\n"; + } + if (TryGetString_(uciMetricRecordGetDescriptor, record, descriptor)) { + oss << "record[" << i << "].descriptor=\"" << descriptor << "\"\n"; + } + if (TryGetString_(uciMetricRecordGetUnit, record, unit)) { + oss << "record[" << i << "].unit=\"" << unit << "\"\n"; + } + if (TryGetSample_(uciMetricRecordGetSample, record, sample)) { + oss << "record[" << i << "].sample=" << sample << '\n'; + } + if (TryGetDuration_(uciMetricRecordGetRecordTimestamp, record, timestamp)) { + oss << "record[" << i << "].timestamp=" << timestamp << '\n'; + } + if (TryGetDuration_(uciMetricRecordGetRecordDuration, record, duration)) { + oss << "record[" << i << "].duration=" << duration << '\n'; + } + } + + pmlog_verb(v::uci)(oss.str()); + } + + std::optional TryParseCoreIndex_(std::string_view entity) + { + if (!entity.starts_with(kCoreEntityPrefix_)) { + return std::nullopt; + } + + const auto suffix = entity.substr(kCoreEntityPrefix_.size()); + if (suffix.empty()) { + return std::nullopt; + } + + try { + const std::string suffixString{ suffix }; + size_t parsedChars = 0; + const auto value = std::stoul(suffixString, &parsedChars); + if (parsedChars != suffixString.size() || value > uint32_t(-1)) { + return std::nullopt; + } + return (uint32_t)value; + } + catch (const std::exception&) { + return std::nullopt; + } + } + + bool IsCpuTemperatureRecord_( + std::string_view metricName, + std::string_view entity) + { + return metricName == kCpuTemperatureRecordMetricName_ && + TryParseCoreIndex_(entity).has_value(); + } + + void AppendQuotedMetricName_(std::string& metricsJson, std::string_view metricName) + { + if (!metricsJson.empty()) { + metricsJson += ", "; + } + metricsJson += std::format("\"{}\"", metricName); + } + } + + std::atomic UciTelemetryProvider::activeProvider_{ nullptr }; + + UciTelemetryProvider::UciTelemetryProvider() + { + CheckUciCall_( + uciGetCollectorFromIdentifier(SoCWatchIdentifier, &collector_), + "uciGetCollectorFromIdentifier", + true); + CheckUciCall_(uciInitialize(collector_), "uciInitialize", true); + + device_.providerDeviceId = kProviderDeviceId_; + device_.physicalCoreCount = CountPhysicalCores_(); + device_.fingerprint = BuildFingerprint_(); + enumeratedMetricNames_ = EnumerateMetrics_(); + device_.caps = BuildCaps_(enumeratedMetricNames_, device_.physicalCoreCount); + device_.samples.cpuTemperatures.resize(device_.physicalCoreCount, 0.0); + device_.samples.hasCpuTemperature.resize(device_.physicalCoreCount, false); + } + + UciTelemetryProvider::~UciTelemetryProvider() + { + StopCollection_(); + auto* expected = this; + activeProvider_.compare_exchange_strong(expected, nullptr); + if (collector_) { + uciDestroy(collector_); + } + } + + ProviderCapabilityMap UciTelemetryProvider::GetCaps() + { + ProviderCapabilityMap capsByDeviceId{}; + capsByDeviceId.emplace(kProviderDeviceId_, device_.caps); + return capsByDeviceId; + } + + const TelemetryDeviceFingerprint& UciTelemetryProvider::GetFingerPrint( + ProviderDeviceId providerDeviceId) const + { + if (providerDeviceId == kProviderDeviceId_) { + return device_.fingerprint; + } + throw Except<>("UCI provider device not found"); + } + + TelemetryMetricValue UciTelemetryProvider::PollMetric( + ProviderDeviceId providerDeviceId, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) + { + (void)requestQpc; + + if (providerDeviceId != kProviderDeviceId_) { + throw Except<>("UCI provider device not found"); + } + + std::lock_guard dataLock{ dataMutex_ }; + ValidateMetricIndex_(device_, metricId, arrayIndex); + + switch (metricId) { + case PM_METRIC_CPU_POWER: + return device_.samples.hasCpuPower ? device_.samples.cpuPower : 0.0; + case PM_METRIC_CPU_TEMPERATURE: + return device_.samples.hasCpuTemperature[arrayIndex] ? + device_.samples.cpuTemperatures[arrayIndex] : 0.0; + default: + throw Except<>("Unsupported metric for UCI provider"); + } + } + + void UciTelemetryProvider::SetPollRate(uint32_t pollRateMs) + { + std::lock_guard configLock{ configMutex_ }; + const auto effectivePollRateMs = std::max(pollRateMs, 1u); + if (pollRateMs_ == effectivePollRateMs) { + return; + } + + pollRateMs_ = effectivePollRateMs; + ReconfigureCollection_(); + } + + void UciTelemetryProvider::SetMetricUse(const svc::DeviceMetricUse& metricUse) + { + std::lock_guard configLock{ configMutex_ }; + std::unordered_set systemMetricUse; + if (const auto it = metricUse.find(ipc::kSystemDeviceId); it != metricUse.end()) { + systemMetricUse = it->second; + } + + if (metricUse_ == systemMetricUse) { + return; + } + + metricUse_ = std::move(systemMetricUse); + ReconfigureCollection_(); + } + + void UciTelemetryProvider::StaticDataCallback_(uciDataBundle* dataBundle) + { + if (auto* pProvider = activeProvider_.load(std::memory_order_acquire)) { + pProvider->OnDataCallback_(dataBundle); + } + } + + uint32_t UciTelemetryProvider::CountPhysicalCores_() + { + DWORD bytes = 0; + GetLogicalProcessorInformationEx(RelationProcessorCore, nullptr, &bytes); + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER || bytes == 0) { + return 1; + } + + std::vector buffer(bytes); + if (!GetLogicalProcessorInformationEx( + RelationProcessorCore, + (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)buffer.data(), + &bytes)) { + return 1; + } + + uint32_t coreCount = 0; + for (DWORD offset = 0; offset < bytes;) { + const auto* pInfo = + (const SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(buffer.data() + offset); + if (pInfo->Relationship == RelationProcessorCore) { + ++coreCount; + } + offset += pInfo->Size; + } + + return coreCount != 0 ? coreCount : 1; + } + + void UciTelemetryProvider::ValidateMetricIndex_( + const DeviceState_& device, + PM_METRIC metricId, + uint32_t arrayIndex) + { + switch (metricId) { + case PM_METRIC_CPU_POWER: + if (arrayIndex != 0) { + throw Except<>("UCI scalar metric queried with nonzero array index"); + } + return; + case PM_METRIC_CPU_TEMPERATURE: + if (arrayIndex >= device.samples.cpuTemperatures.size()) { + throw Except<>("UCI CPU temperature queried with out-of-range array index"); + } + return; + default: + throw Except<>("Unsupported UCI metric queried"); + } + } + + TelemetryDeviceFingerprint UciTelemetryProvider::BuildFingerprint_() + { + TelemetryDeviceFingerprint fingerprint{}; + fingerprint.deviceType = PM_DEVICE_TYPE_SYSTEM; + return fingerprint; + } + + ipc::MetricCapabilities UciTelemetryProvider::BuildCaps_( + const std::unordered_set& enumeratedMetricNames, + uint32_t physicalCoreCount) + { + ipc::MetricCapabilities caps{}; + if (enumeratedMetricNames.contains(std::string{ kCpuPowerMetricName_ })) { + caps.Set(PM_METRIC_CPU_POWER, 1); + } + if (enumeratedMetricNames.contains(std::string{ kCpuTemperatureMetricName_ })) { + caps.Set(PM_METRIC_CPU_TEMPERATURE, physicalCoreCount != 0 ? physicalCoreCount : 1); + } + return caps; + } + + std::unordered_set UciTelemetryProvider::EnumerateMetrics_() + { + MetricContainerGuard_ metricContainer{}; + CheckUciCall_(uciEnumerateMetrics(collector_, &metricContainer.handle), "uciEnumerateMetrics"); + + if (util::log::GlobalPolicy::VCheck(v::uci)) { + DumpMetricEnumeration_(metricContainer.handle); + } + + uint32_t metricCount = 0; + uciMetricHandle* pMetrics = nullptr; + CheckUciCall_( + uciGetMetricContainerMetrics(metricContainer.handle, &metricCount, &pMetrics), + "uciGetMetricContainerMetrics"); + + std::unordered_set enumeratedMetricNames{}; + for (uint32_t i = 0; i < metricCount; ++i) { + std::string metricName; + if (!TryGetString_(uciGetMetricName, pMetrics[i], metricName) || metricName.empty()) { + continue; + } + + enumeratedMetricNames.emplace(util::str::ToLower(metricName)); + } + + return enumeratedMetricNames; + } + + void UciTelemetryProvider::DumpMetricEnumeration_(uciMetricContainerHandle metricContainer) const + { + std::ostringstream oss; + oss << "UCI metric enumeration dump\n"; + + uint32_t metricCount = 0; + uciMetricHandle* pMetrics = nullptr; + auto result = uciGetMetricContainerMetrics(metricContainer, &metricCount, &pMetrics); + oss << "metrics.result=" << (int)result << " metrics.count=" << metricCount << '\n'; + if (result == UC_SUCCESS && pMetrics != nullptr) { + for (uint32_t i = 0; i < metricCount; ++i) { + uint32_t metricId = 0; + std::string metricName; + std::string metricDescription; + auto metricIdResult = uciGetMetricId(pMetrics[i], &metricId); + TryGetString_(uciGetMetricName, pMetrics[i], metricName); + TryGetString_(uciGetMetricDescription, pMetrics[i], metricDescription); + oss << std::format( + "metric[{}] id.result={} id={} name=\"{}\" description=\"{}\"\n", + i, + (int)metricIdResult, + metricId, + metricName, + metricDescription); + + uint32_t eventCount = 0; + uciMetricEventHandle* pEvents = nullptr; + auto eventResult = uciGetMetricEvents(pMetrics[i], &eventCount, &pEvents); + oss << std::format( + "metric[{}].events.result={} metric[{}].events.count={}\n", + i, + (int)eventResult, + i, + eventCount); + if (eventResult == UC_SUCCESS && pEvents != nullptr) { + for (uint32_t j = 0; j < eventCount; ++j) { + uint32_t eventId = 0; + std::string eventName; + std::string eventDescription; + auto eventIdResult = uciGetEventId(pEvents[j], &eventId); + TryGetString_(uciGetMetricEventName, pEvents[j], eventName); + TryGetString_(uciGetMetricEventDescription, pEvents[j], eventDescription); + oss << std::format( + "metric[{}].event[{}] id.result={} id={} name=\"{}\" description=\"{}\"\n", + i, + j, + (int)eventIdResult, + eventId, + eventName, + eventDescription); + } + } + } + } + + uint32_t groupCount = 0; + uciMetricGroupHandle* pGroups = nullptr; + result = uciGetMetricContainerGroups(metricContainer, &groupCount, &pGroups); + oss << "groups.result=" << (int)result << " groups.count=" << groupCount << '\n'; + if (result == UC_SUCCESS && pGroups != nullptr) { + for (uint32_t i = 0; i < groupCount; ++i) { + uint32_t groupId = 0; + std::string groupName; + std::string groupDescription; + auto groupIdResult = uciGetMetricGroupId(pGroups[i], &groupId); + TryGetString_(uciGetMetricGroupName, pGroups[i], groupName); + TryGetString_(uciGetMetricGroupDescription, pGroups[i], groupDescription); + oss << std::format( + "group[{}] id.result={} id={} name=\"{}\" description=\"{}\"\n", + i, + (int)groupIdResult, + groupId, + groupName, + groupDescription); + + uint32_t groupMetricCount = 0; + uciMetricHandle* pGroupMetrics = nullptr; + auto groupMetricResult = + uciGetMetricsInGroup(pGroups[i], &groupMetricCount, &pGroupMetrics); + oss << std::format( + "group[{}].metrics.result={} group[{}].metrics.count={}\n", + i, + (int)groupMetricResult, + i, + groupMetricCount); + if (groupMetricResult == UC_SUCCESS && pGroupMetrics != nullptr) { + for (uint32_t j = 0; j < groupMetricCount; ++j) { + std::string groupMetricName; + std::string groupMetricDescription; + TryGetString_(uciGetMetricName, pGroupMetrics[j], groupMetricName); + TryGetString_(uciGetMetricDescription, pGroupMetrics[j], groupMetricDescription); + oss << std::format( + "group[{}].metric[{}] name=\"{}\" description=\"{}\"\n", + i, + j, + groupMetricName, + groupMetricDescription); + } + } + } + } + + uint32_t containerEventCount = 0; + uciMetricEventHandle* pContainerEvents = nullptr; + result = uciGetMetricContainerEvents( + metricContainer, + &containerEventCount, + &pContainerEvents); + oss << "container.events.result=" << (int)result + << " container.events.count=" << containerEventCount << '\n'; + if (result == UC_SUCCESS && pContainerEvents != nullptr) { + for (uint32_t i = 0; i < containerEventCount; ++i) { + uint32_t eventId = 0; + std::string eventName; + std::string eventDescription; + auto eventIdResult = uciGetEventId(pContainerEvents[i], &eventId); + TryGetString_(uciGetMetricEventName, pContainerEvents[i], eventName); + TryGetString_(uciGetMetricEventDescription, pContainerEvents[i], eventDescription); + oss << std::format( + "container.event[{}] id.result={} id={} name=\"{}\" description=\"{}\"\n", + i, + (int)eventIdResult, + eventId, + eventName, + eventDescription); + } + } + + pmlog_verb(v::uci)(oss.str()); + } + + void UciTelemetryProvider::OnDataCallback_(uciDataBundle* dataBundle) + { + if (util::log::GlobalPolicy::VCheck(v::uci)) { + DumpDataCallback_(dataBundle); + } + + if (dataBundle == nullptr || dataBundle->records == nullptr || dataBundle->numRecords == 0) { + return; + } + + std::lock_guard dataLock{ dataMutex_ }; + for (uint16_t i = 0; i < dataBundle->numRecords; ++i) { + ApplyMetricRecord_(device_, dataBundle->records[i]); + } + } + + void UciTelemetryProvider::ApplyMetricRecord_(DeviceState_& device, void* recordHandle) + { + const auto record = (uciMetricRecordHandle)recordHandle; + std::string metricName; + if (!TryGetString_(uciMetricRecordGetMetricName, record, metricName) || metricName.empty()) { + return; + } + + double sample = 0.0; + if (!TryGetSample_(uciMetricRecordGetSample, record, sample)) { + return; + } + + if (metricName == kCpuPowerRecordMetricName_) { + uint64_t duration = 0; + if (!TryGetDuration_(uciMetricRecordGetRecordDuration, record, duration) || duration == 0) { + return; + } + + const auto durationSeconds = double(duration) / 1'000'000'000.0; + if (durationSeconds <= 0.0) { + return; + } + + device.samples.cpuPower = (sample / durationSeconds) / 1000.0; + device.samples.hasCpuPower = true; + return; + } + + std::string entity; + TryGetString_(uciMetricRecordGetEntity, record, entity); + + if (!IsCpuTemperatureRecord_(metricName, entity)) { + return; + } + + if (const auto coreIndex = TryParseCoreIndex_(entity)) { + if (*coreIndex < device.samples.cpuTemperatures.size()) { + device.samples.cpuTemperatures[*coreIndex] = sample; + device.samples.hasCpuTemperature[*coreIndex] = true; + } + return; + } + + } + + void UciTelemetryProvider::ReconfigureCollection_() + { + if (!collector_) { + return; + } + + bool wantsCpuPower = false; + bool wantsCpuTemperature = false; + for (const auto& use : metricUse_) { + if (use.metricId == PM_METRIC_CPU_POWER && + enumeratedMetricNames_.contains(std::string{ kCpuPowerMetricName_ })) { + wantsCpuPower = true; + } + else if (use.metricId == PM_METRIC_CPU_TEMPERATURE && + enumeratedMetricNames_.contains(std::string{ kCpuTemperatureMetricName_ })) { + wantsCpuTemperature = true; + } + } + + const bool wantsCollection = wantsCpuPower || wantsCpuTemperature; + if (!wantsCollection) { + StopCollection_(); + std::lock_guard dataLock{ dataMutex_ }; + device_.samples.cpuPower = 0.0; + device_.samples.hasCpuPower = false; + std::fill(device_.samples.cpuTemperatures.begin(), device_.samples.cpuTemperatures.end(), 0.0); + std::fill(device_.samples.hasCpuTemperature.begin(), device_.samples.hasCpuTemperature.end(), false); + return; + } + + StopCollection_(); + + std::string metricsJson; + if (wantsCpuPower) { + AppendQuotedMetricName_(metricsJson, kCpuPowerMetricName_); + } + if (wantsCpuTemperature) { + AppendQuotedMetricName_(metricsJson, kCpuTemperatureMetricName_); + } + + const auto configJson = std::format( + R"json( +{{ + "collectorIdentifier": {{ + "name": "socwatch", + "guid": "54B46B56-5439-4D29-8B07-15863D1F6EC6", + "version": "0.1.0" + }}, + "collectionParams": {{ + "samplingInterval": {}, + "isContinuous": true, + "maxDetail": true + }}, + "metrics": [ {} ], + "outputParams": {{ + "outputFormats": [ "data-callback" ], + "outputPath": "UCI_metrics" + }} +}} +)json", + pollRateMs_, + metricsJson); + + CheckUciCall_(uciConfigureCollection(collector_, configJson.c_str()), "uciConfigureCollection"); + CheckUciCall_(uciSetDataCallback(collector_, &StaticDataCallback_), "uciSetDataCallback"); + + auto* expected = (UciTelemetryProvider*)nullptr; + if (!activeProvider_.compare_exchange_strong(expected, this, std::memory_order_acq_rel)) { + activeProvider_.store(this, std::memory_order_release); + } + + CheckUciCall_(uciStartCollection(collector_), "uciStartCollection"); + collectionStarted_ = true; + } + + void UciTelemetryProvider::StopCollection_() noexcept + { + if (!collectionStarted_ || !collector_) { + return; + } + + const auto result = uciStopCollection(collector_); + if (result != UC_SUCCESS && + result != UC_ERROR_COLLECTION_NOT_RUNNING) { + pmlog_warn("uciStopCollection failed").pmwatch((int)result); + } + collectionStarted_ = false; + } +} diff --git a/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.h b/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.h new file mode 100644 index 00000000..93ca8dcc --- /dev/null +++ b/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.h @@ -0,0 +1,81 @@ +// Copyright (C) 2026 Intel Corporation +// SPDX-License-Identifier: MIT +#pragma once + +#include "../../CommonUtilities/win/WinAPI.h" +#include "../../Interprocess/source/SystemDeviceId.h" +#include "../TelemetryProvider.h" +#include "inc/uci/uci-data-records.h" +#include "inc/uci/uci.h" + +#include +#include +#include +#include +#include +#include + +namespace pmon::tel::uci +{ + class UciTelemetryProvider : public TelemetryProvider + { + public: + UciTelemetryProvider(); + ~UciTelemetryProvider() override; + ProviderCapabilityMap GetCaps() override; + const TelemetryDeviceFingerprint& GetFingerPrint(ProviderDeviceId providerDeviceId) const override; + TelemetryMetricValue PollMetric( + ProviderDeviceId providerDeviceId, + PM_METRIC metricId, + uint32_t arrayIndex, + int64_t requestQpc) override; + void SetPollRate(uint32_t pollRateMs) override; + void SetMetricUse(const svc::DeviceMetricUse& metricUse) override; + + private: + struct SampleState_ + { + double cpuPower = 0.0; + bool hasCpuPower = false; + std::vector cpuTemperatures{}; + std::vector hasCpuTemperature{}; + }; + + struct DeviceState_ + { + ProviderDeviceId providerDeviceId = 0; + TelemetryDeviceFingerprint fingerprint{}; + ipc::MetricCapabilities caps{}; + uint32_t physicalCoreCount = 1; + SampleState_ samples{}; + }; + + static void StaticDataCallback_(uciDataBundle* dataBundle); + static uint32_t CountPhysicalCores_(); + static void ValidateMetricIndex_(const DeviceState_& device, PM_METRIC metricId, uint32_t arrayIndex); + static TelemetryDeviceFingerprint BuildFingerprint_(); + static ipc::MetricCapabilities BuildCaps_( + const std::unordered_set& enumeratedMetricNames, + uint32_t physicalCoreCount); + + void OnDataCallback_(uciDataBundle* dataBundle); + void ApplyMetricRecord_(DeviceState_& device, void* recordHandle); + std::unordered_set EnumerateMetrics_(); + void DumpMetricEnumeration_(uciMetricContainerHandle metricContainer) const; + void ReconfigureCollection_(); + void StopCollection_() noexcept; + + private: + static constexpr ProviderDeviceId kProviderDeviceId_ = 1; + uciCollectorHandle collector_ = nullptr; + DeviceState_ device_{}; + std::mutex configMutex_{}; + std::mutex dataMutex_{}; + std::unordered_set metricUse_{}; + std::unordered_set enumeratedMetricNames_{}; + uint32_t pollRateMs_ = 1000; + bool collectionStarted_ = false; + + static std::atomic activeProvider_; + }; +} diff --git a/IntelPresentMon/Interprocess/source/metadata/MetricList.h b/IntelPresentMon/Interprocess/source/metadata/MetricList.h index 25c65e54..a6900711 100644 --- a/IntelPresentMon/Interprocess/source/metadata/MetricList.h +++ b/IntelPresentMon/Interprocess/source/metadata/MetricList.h @@ -96,4 +96,4 @@ X_(PM_METRIC_BETWEEN_APP_START, PM_METRIC_TYPE_FRAME_EVENT, PM_UNIT_MILLISECONDS, PM_DATA_TYPE_VOID, PM_DATA_TYPE_DOUBLE, 0, PM_DEVICE_TYPE_INDEPENDENT, FULL_STATS) \ X_(PM_METRIC_FLIP_DELAY, PM_METRIC_TYPE_FRAME_EVENT, PM_UNIT_MILLISECONDS, PM_DATA_TYPE_VOID, PM_DATA_TYPE_DOUBLE, 0, PM_DEVICE_TYPE_INDEPENDENT, FULL_STATS) \ X_(PM_METRIC_SESSION_START_QPC, PM_METRIC_TYPE_STATIC, PM_UNIT_QPC, PM_DATA_TYPE_UINT64, PM_DATA_TYPE_UINT64, 0, PM_DEVICE_TYPE_INDEPENDENT, PM_STAT_NONE) \ - X_(PM_METRIC_COUNT_, PM_METRIC_TYPE_STATIC, PM_UNIT_DIMENSIONLESS, PM_DATA_TYPE_VOID, PM_DATA_TYPE_VOID, PM_ENUM_NULL_ENUM, PM_DEVICE_TYPE_INDEPENDENT, PM_STAT_NONE) \ + X_(PM_METRIC_COUNT_, PM_METRIC_TYPE_STATIC, PM_UNIT_DIMENSIONLESS, PM_DATA_TYPE_VOID, PM_DATA_TYPE_VOID, PM_ENUM_NULL_ENUM, PM_DEVICE_TYPE_INDEPENDENT, PM_STAT_NONE) diff --git a/IntelPresentMon/PMInstallerLib/Library.wxs b/IntelPresentMon/PMInstallerLib/Library.wxs index 69c7b023..4edfcbfa 100644 --- a/IntelPresentMon/PMInstallerLib/Library.wxs +++ b/IntelPresentMon/PMInstallerLib/Library.wxs @@ -84,6 +84,7 @@ + diff --git a/IntelPresentMon/PMInstallerLib/PMInstallerLib.wixproj b/IntelPresentMon/PMInstallerLib/PMInstallerLib.wixproj index 589c359b..e7dd91de 100644 --- a/IntelPresentMon/PMInstallerLib/PMInstallerLib.wixproj +++ b/IntelPresentMon/PMInstallerLib/PMInstallerLib.wixproj @@ -5,6 +5,7 @@ PMInstallerLib $(SolutionDir)build\obj\$(MSBuildProjectName)-$(Platform)-$(Configuration) $(SolutionDir)build\$(Configuration) + $(DefineConstants);UciDistDir=$(MSBuildProjectDirectory)\..\ControlLib\uci\dist $(WIX)bin\ $(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets @@ -14,6 +15,7 @@ + @@ -33,5 +35,8 @@ INSTALLFOLDER + + + - \ No newline at end of file + diff --git a/IntelPresentMon/PMInstallerLib/UciDist.wxs b/IntelPresentMon/PMInstallerLib/UciDist.wxs new file mode 100644 index 00000000..abf3d68f --- /dev/null +++ b/IntelPresentMon/PMInstallerLib/UciDist.wxs @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/IntelPresentMon/PMInstallerLib/wix-uci-dist.ps1 b/IntelPresentMon/PMInstallerLib/wix-uci-dist.ps1 new file mode 100644 index 00000000..5d5f5046 --- /dev/null +++ b/IntelPresentMon/PMInstallerLib/wix-uci-dist.ps1 @@ -0,0 +1,92 @@ +[CmdletBinding()] +param() + +function Get-DeterministicGuid { + param( + [Parameter(Mandatory = $true)] + [string]$Name + ) + + $md5 = [System.Security.Cryptography.MD5]::Create() + try { + $bytes = $md5.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($Name.ToLowerInvariant())) + } + finally { + $md5.Dispose() + } + + $bytes[6] = ($bytes[6] -band 0x0F) -bor 0x30 + $bytes[8] = ($bytes[8] -band 0x3F) -bor 0x80 + return (New-Object System.Guid -ArgumentList (, $bytes)).ToString().ToUpperInvariant() +} + +if (-not $env:WIX) { + Write-Error 'Environment variable WIX is not set. Please install WIX or set WIX to the WiX installation directory.' + exit 1 +} + +$heatExe = Join-Path $env:WIX 'bin\heat.exe' +if (-not (Test-Path $heatExe)) { + Write-Error "heat.exe not found at '$heatExe'. Verify your WIX environment variable points to the correct location." + exit 1 +} + +Push-Location $PSScriptRoot + +if (-not (Test-Path '..\ControlLib\uci\dist')) { + Pop-Location + Write-Error "Expected '..\\ControlLib\\uci\\dist' to exist before harvesting UCI payload files." + exit 1 +} + +$outPath = 'UciDist.wxs' + +& $heatExe dir '..\ControlLib\uci\dist' ` + -srd -sreg -scom ` + -dr service_folder ` + -cg uci_dist_files ` + -var var.UciDistDir ` + -suid -g1 -ag ` + -out $outPath + +$code = $LASTEXITCODE +if ($code -ne 0) { + Pop-Location + Write-Error "heat.exe failed for '..\\ControlLib\\uci\\dist' (exit code $code)" + exit $code +} + +[xml]$doc = Get-Content $outPath +$ns = New-Object System.Xml.XmlNamespaceManager($doc.NameTable) +$ns.AddNamespace('w', 'http://schemas.microsoft.com/wix/2006/wi') + +$componentNodes = $doc.SelectNodes('//w:Component', $ns) +foreach ($componentNode in $componentNodes) { + $componentNode.SetAttribute('Win64', 'yes') + $fileNode = $componentNode.SelectSingleNode('w:File', $ns) + if ($null -eq $fileNode) { + Pop-Location + Write-Error 'Encountered a harvested component without a File node.' + exit 1 + } + + $source = $fileNode.GetAttribute('Source') + $guid = Get-DeterministicGuid -Name $source + $componentNode.SetAttribute('Guid', "{$guid}") +} + +$settings = New-Object System.Xml.XmlWriterSettings +$settings.Encoding = New-Object System.Text.UTF8Encoding($false) +$settings.Indent = $true +$settings.IndentChars = ' ' +$settings.NewLineChars = "`r`n" +$settings.NewLineHandling = [System.Xml.NewLineHandling]::Replace + +$writer = [System.Xml.XmlWriter]::Create((Resolve-Path $outPath), $settings) +try { + $doc.Save($writer) +} +finally { + $writer.Dispose() + Pop-Location +} diff --git a/IntelPresentMon/PresentMonService/PMMainThread.cpp b/IntelPresentMon/PresentMonService/PMMainThread.cpp index a02cafb6..3edb5ec0 100644 --- a/IntelPresentMon/PresentMonService/PMMainThread.cpp +++ b/IntelPresentMon/PresentMonService/PMMainThread.cpp @@ -127,7 +127,7 @@ void TelemetryThreadEntry_(Service* const srv, PresentMon* const pm, ipc::Servic } pmon::util::QpcTimer timer; - pmon::tel::TelemetryCoordinator coordinator; + pmon::tel::TelemetryCoordinator coordinator{ pm->GetGpuTelemetryPeriod() }; coordinator.RegisterDevicesToIpc(*pComms); coordinator.PopulateStaticsToIpc(*pComms); if (const auto cpuInfo = coordinator.GetCpuInfo()) { @@ -148,6 +148,7 @@ void TelemetryThreadEntry_(Service* const srv, PresentMon* const pm, ipc::Servic auto pMetricUse = pm->GetDeviceMetricUsageSnapshot(); if (!pMetricUse || pMetricUse->empty()) { + coordinator.SetMetricUse({}); pmlog_dbg("received device usage event, but no telemetry device metrics were active"); continue; } @@ -160,12 +161,16 @@ void TelemetryThreadEntry_(Service* const srv, PresentMon* const pm, ipc::Servic pMetricUse = pm->GetDeviceMetricUsageSnapshot(); if (!pMetricUse || pMetricUse->empty()) { + coordinator.SetMetricUse({}); break; } + const auto telemetryPeriodMs = pm->GetGpuTelemetryPeriod(); + coordinator.SetPollRate(telemetryPeriodMs); + coordinator.SetMetricUse(*pMetricUse); coordinator.PollToIpc(*pMetricUse, *pComms); - waiter.SetInterval(pm->GetGpuTelemetryPeriod() / 1000.); + waiter.SetInterval(telemetryPeriodMs / 1000.); waiter.Wait(); } } diff --git a/IntelPresentMon/metrics.csv b/IntelPresentMon/metrics.csv index 4c109e47..ffdd5397 100644 --- a/IntelPresentMon/metrics.csv +++ b/IntelPresentMon/metrics.csv @@ -1,4 +1,4 @@ -// WARNING: ensure this file is saved in text CSV format when modifying this file,,, +// WARNING: ensure this file is saved in text CSV format when modifying this file,,, // PM_METRIC,IPM_ONLY,NAME,DESCRIPTION ,,, PM_METRIC_APPLICATION,,Application,The name of the process that generated the frame. @@ -78,11 +78,11 @@ PM_METRIC_GPU_MEM_UTILIZATION_LIMITED,1,GPU Memory Utilization Limited,Memory fr PM_METRIC_CPU_UTILIZATION,1,CPU Utilization,Amount of CPU processing capacity being used. PM_METRIC_CPU_POWER_LIMIT,1,CPU Power Limit,Power limit of the CPU. PM_METRIC_CPU_POWER,1,CPU Power,Power consumed by the CPU. -PM_METRIC_CPU_TEMPERATURE,1,CPU Temperature,Temperature of the CPU. +PM_METRIC_CPU_TEMPERATURE,1,CPU Temperature,Temperature of each physical CPU core. PM_METRIC_CPU_FREQUENCY,1,CPU Frequency,Clock speed of the CPU. PM_METRIC_CPU_CORE_UTILITY,1,CPU Core Utility,Amount of CPU processing utility being used per core. ,,, -PM_METRIC_INSTRUMENTED_LATENCY,,Instrumented Latency,Instrumented Frame Start To Display Latency,How long it took from the instrumented start of this frame until the frame was displayed on the screen. +PM_METRIC_INSTRUMENTED_LATENCY,,Instrumented Latency,How long it took from the instrumented start of this frame until the frame was displayed on the screen. PM_METRIC_GPU_EFFECTIVE_FREQUENCY,1,GPU Effective Frequency,Effective clock speed of the GPU cores. PM_METRIC_GPU_VOLTAGE_REGULATOR_TEMPERATURE,1,GPU Voltage Regulator Temperature,Effective clock speed of the GPU cores. PM_METRIC_GPU_MEM_EFFECTIVE_BANDWIDTH,1,GPU Memory Effective Bandwidth,Data transfer rate that the memory modules can sustain based on current clock frequency. diff --git a/Tools/generate/EnumMetric/metrics.awk b/Tools/generate/EnumMetric/metrics.awk index b3750f56..560944cb 100644 --- a/Tools/generate/EnumMetric/metrics.awk +++ b/Tools/generate/EnumMetric/metrics.awk @@ -7,6 +7,7 @@ BEGIN{ } { n = split($1, a, ",") + sub(/^\357\273\277/, "", a[1]) #printf "\n%u:%u: ", NF, n #for (i = 1; i <= n; ++i) printf "|%s", a[i] @@ -16,6 +17,7 @@ BEGIN{ if (a[1] == "") next if (substr(a[1], 1, 2) == "//") next + if (substr(a[1], 1, 10) != "PM_METRIC_") next if (NF == 1) { name = a[3] From 24a1f19316278808c36db9e774b51ddee12126d2 Mon Sep 17 00:00:00 2001 From: Chili Date: Tue, 17 Mar 2026 11:24:41 +0900 Subject: [PATCH 23/42] log poll/parse errors uci --- IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp b/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp index d069f40c..df75baf6 100644 --- a/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp @@ -142,11 +142,13 @@ namespace pmon::tel::uci std::optional TryParseCoreIndex_(std::string_view entity) { if (!entity.starts_with(kCoreEntityPrefix_)) { + pmlog_dbg("unexpected core entity").pmwatch(entity); return std::nullopt; } const auto suffix = entity.substr(kCoreEntityPrefix_.size()); if (suffix.empty()) { + pmlog_dbg("missing core index").pmwatch(entity); return std::nullopt; } @@ -155,11 +157,14 @@ namespace pmon::tel::uci size_t parsedChars = 0; const auto value = std::stoul(suffixString, &parsedChars); if (parsedChars != suffixString.size() || value > uint32_t(-1)) { + pmlog_dbg("unexpected parsed chars or value") + .pmwatch(entity).pmwatch(parsedChars).pmwatch(value); return std::nullopt; } return (uint32_t)value; } catch (const std::exception&) { + pmlog_dbg(util::ReportException("Parse failure")); return std::nullopt; } } @@ -538,22 +543,26 @@ namespace pmon::tel::uci const auto record = (uciMetricRecordHandle)recordHandle; std::string metricName; if (!TryGetString_(uciMetricRecordGetMetricName, record, metricName) || metricName.empty()) { + pmlog_dbg("Could not get record metric name"); return; } double sample = 0.0; if (!TryGetSample_(uciMetricRecordGetSample, record, sample)) { + pmlog_dbg("Could not get record sample"); return; } if (metricName == kCpuPowerRecordMetricName_) { uint64_t duration = 0; if (!TryGetDuration_(uciMetricRecordGetRecordDuration, record, duration) || duration == 0) { + pmlog_dbg("Could not get record duration"); return; } const auto durationSeconds = double(duration) / 1'000'000'000.0; if (durationSeconds <= 0.0) { + pmlog_dbg("Negative duration").pmwatch(durationSeconds); return; } From d17b0cecba371c8258d93319759f0a2d1a729937 Mon Sep 17 00:00:00 2001 From: Chili Date: Tue, 17 Mar 2026 11:55:54 +0900 Subject: [PATCH 24/42] uci lifecycle logging --- .../ControlLib/uci/UciTelemetryProvider.cpp | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp b/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp index df75baf6..9ebeddac 100644 --- a/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp @@ -203,6 +203,11 @@ namespace pmon::tel::uci device_.caps = BuildCaps_(enumeratedMetricNames_, device_.physicalCoreCount); device_.samples.cpuTemperatures.resize(device_.physicalCoreCount, 0.0); device_.samples.hasCpuTemperature.resize(device_.physicalCoreCount, false); + + pmlog_info(std::format( + "UCI telemetry provider initialized successfully; physicalCores={} enumeratedMetrics={}", + device_.physicalCoreCount, + enumeratedMetricNames_.size())); } UciTelemetryProvider::~UciTelemetryProvider() @@ -608,7 +613,15 @@ namespace pmon::tel::uci } const bool wantsCollection = wantsCpuPower || wantsCpuTemperature; + pmlog_dbg(std::format( + "Configuring UCI collection; pollRateMs={} wantsCpuPower={} wantsCpuTemperature={} collectionStarted={}", + pollRateMs_, + wantsCpuPower, + wantsCpuTemperature, + collectionStarted_)); + if (!wantsCollection) { + pmlog_dbg("Stopping UCI collection because no supported UCI metrics are requested"); StopCollection_(); std::lock_guard dataLock{ dataMutex_ }; device_.samples.cpuPower = 0.0; @@ -651,6 +664,12 @@ namespace pmon::tel::uci pollRateMs_, metricsJson); + pmlog_dbg(std::format( + "Applying UCI collection configuration; pollRateMs={} metrics=[{}]", + pollRateMs_, + metricsJson)); + pmlog_verb(v::uci)(std::format("UCI collection config JSON:\n{}", configJson)); + CheckUciCall_(uciConfigureCollection(collector_, configJson.c_str()), "uciConfigureCollection"); CheckUciCall_(uciSetDataCallback(collector_, &StaticDataCallback_), "uciSetDataCallback"); @@ -659,6 +678,11 @@ namespace pmon::tel::uci activeProvider_.store(this, std::memory_order_release); } + pmlog_dbg(std::format( + "Starting UCI collection; pollRateMs={} wantsCpuPower={} wantsCpuTemperature={}", + pollRateMs_, + wantsCpuPower, + wantsCpuTemperature)); CheckUciCall_(uciStartCollection(collector_), "uciStartCollection"); collectionStarted_ = true; } @@ -669,6 +693,7 @@ namespace pmon::tel::uci return; } + pmlog_dbg("Stopping UCI collection"); const auto result = uciStopCollection(collector_); if (result != UC_SUCCESS && result != UC_ERROR_COLLECTION_NOT_RUNNING) { From 73212c9841e9c1c9fc676e754260694213fee784 Mon Sep 17 00:00:00 2001 From: Chili Date: Fri, 20 Mar 2026 10:31:23 +0900 Subject: [PATCH 25/42] cleanup --- .../ControlLib/uci/UciTelemetryProvider.cpp | 199 +++++++++--------- .../ControlLib/uci/UciTelemetryProvider.h | 18 +- 2 files changed, 101 insertions(+), 116 deletions(-) diff --git a/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp b/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp index 9ebeddac..2f49dbfc 100644 --- a/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp @@ -14,12 +14,12 @@ #include #include #include -#include #include #include #include using namespace pmon; +using namespace std::literals; namespace pmon::tel::uci { @@ -37,6 +37,12 @@ namespace pmon::tel::uci { uciMetricContainerHandle handle = nullptr; + MetricContainerGuard_() = default; + MetricContainerGuard_(const MetricContainerGuard_&) = delete; + MetricContainerGuard_& operator=(const MetricContainerGuard_&) = delete; + MetricContainerGuard_(MetricContainerGuard_&&) = delete; + MetricContainerGuard_& operator=(MetricContainerGuard_&&) = delete; + ~MetricContainerGuard_() { if (handle != nullptr) { @@ -72,36 +78,26 @@ namespace pmon::tel::uci return true; } - bool TryGetSample_(auto getter, uciMetricRecordHandle record, double& sample) - { - return getter(record, &sample) == UC_SUCCESS; - } - - bool TryGetDuration_(auto getter, uciMetricRecordHandle record, uint64_t& duration) - { - return getter(record, &duration) == UC_SUCCESS; - } - void DumpDataCallback_(uciDataBundle* dataBundle) { - std::ostringstream oss; if (dataBundle == nullptr) { - oss << "UCI callback received null data bundle"; - pmlog_verb(v::uci)(oss.str()); + pmlog_verb(v::uci)("UCI callback received null data bundle"); return; } - oss << "UCI callback received numRecords=" << dataBundle->numRecords << '\n'; + std::string dump = std::format( + "UCI callback received numRecords={}\n", + dataBundle->numRecords); if (dataBundle->records == nullptr) { - oss << "records pointer is null"; - pmlog_verb(v::uci)(oss.str()); + pmlog_verb(v::uci)("records array pointer is null"); return; } for (uint16_t i = 0; i < dataBundle->numRecords; ++i) { const auto record = dataBundle->records[i]; - oss << "record[" << i << "] handle=" << record << '\n'; + dump += std::format("record[{}]\n", i); if (record == nullptr) { + pmlog_verb(v::uci)("record pointer is null"); continue; } @@ -114,29 +110,29 @@ namespace pmon::tel::uci uint64_t duration = 0; if (TryGetString_(uciMetricRecordGetMetricName, record, metricName)) { - oss << "record[" << i << "].metricName=\"" << metricName << "\"\n"; + dump += std::format("record[{}].metricName=\"{}\"\n", i, metricName); } if (TryGetString_(uciMetricRecordGetEntity, record, entity)) { - oss << "record[" << i << "].entity=\"" << entity << "\"\n"; + dump += std::format("record[{}].entity=\"{}\"\n", i, entity); } if (TryGetString_(uciMetricRecordGetDescriptor, record, descriptor)) { - oss << "record[" << i << "].descriptor=\"" << descriptor << "\"\n"; + dump += std::format("record[{}].descriptor=\"{}\"\n", i, descriptor); } if (TryGetString_(uciMetricRecordGetUnit, record, unit)) { - oss << "record[" << i << "].unit=\"" << unit << "\"\n"; + dump += std::format("record[{}].unit=\"{}\"\n", i, unit); } - if (TryGetSample_(uciMetricRecordGetSample, record, sample)) { - oss << "record[" << i << "].sample=" << sample << '\n'; + if (uciMetricRecordGetSample(record, &sample) == UC_SUCCESS) { + dump += std::format("record[{}].sample={}\n", i, sample); } - if (TryGetDuration_(uciMetricRecordGetRecordTimestamp, record, timestamp)) { - oss << "record[" << i << "].timestamp=" << timestamp << '\n'; + if (uciMetricRecordGetRecordTimestamp(record, ×tamp) == UC_SUCCESS) { + dump += std::format("record[{}].timestamp={}\n", i, timestamp); } - if (TryGetDuration_(uciMetricRecordGetRecordDuration, record, duration)) { - oss << "record[" << i << "].duration=" << duration << '\n'; + if (uciMetricRecordGetRecordDuration(record, &duration) == UC_SUCCESS) { + dump += std::format("record[{}].duration={}\n", i, duration); } } - pmlog_verb(v::uci)(oss.str()); + pmlog_verb(v::uci)(dump); } std::optional TryParseCoreIndex_(std::string_view entity) @@ -169,14 +165,6 @@ namespace pmon::tel::uci } } - bool IsCpuTemperatureRecord_( - std::string_view metricName, - std::string_view entity) - { - return metricName == kCpuTemperatureRecordMetricName_ && - TryParseCoreIndex_(entity).has_value(); - } - void AppendQuotedMetricName_(std::string& metricsJson, std::string_view metricName) { if (!metricsJson.empty()) { @@ -196,18 +184,17 @@ namespace pmon::tel::uci true); CheckUciCall_(uciInitialize(collector_), "uciInitialize", true); - device_.providerDeviceId = kProviderDeviceId_; - device_.physicalCoreCount = CountPhysicalCores_(); - device_.fingerprint = BuildFingerprint_(); - enumeratedMetricNames_ = EnumerateMetrics_(); - device_.caps = BuildCaps_(enumeratedMetricNames_, device_.physicalCoreCount); - device_.samples.cpuTemperatures.resize(device_.physicalCoreCount, 0.0); - device_.samples.hasCpuTemperature.resize(device_.physicalCoreCount, false); + systemDevice_.providerDeviceId = kProviderDeviceId_; + systemDevice_.physicalCoreCount = CountPhysicalCores_(); + systemDevice_.fingerprint = BuildFingerprint_(); + const auto enumeratedMetricNames = EnumerateMetrics_(); + systemDevice_.caps = BuildCaps_(enumeratedMetricNames, systemDevice_.physicalCoreCount); + systemDevice_.cpuCoreTemperaturesSample.resize(systemDevice_.physicalCoreCount); pmlog_info(std::format( "UCI telemetry provider initialized successfully; physicalCores={} enumeratedMetrics={}", - device_.physicalCoreCount, - enumeratedMetricNames_.size())); + systemDevice_.physicalCoreCount, + enumeratedMetricNames.size())); } UciTelemetryProvider::~UciTelemetryProvider() @@ -223,7 +210,7 @@ namespace pmon::tel::uci ProviderCapabilityMap UciTelemetryProvider::GetCaps() { ProviderCapabilityMap capsByDeviceId{}; - capsByDeviceId.emplace(kProviderDeviceId_, device_.caps); + capsByDeviceId.emplace(kProviderDeviceId_, systemDevice_.caps); return capsByDeviceId; } @@ -231,7 +218,7 @@ namespace pmon::tel::uci ProviderDeviceId providerDeviceId) const { if (providerDeviceId == kProviderDeviceId_) { - return device_.fingerprint; + return systemDevice_.fingerprint; } throw Except<>("UCI provider device not found"); } @@ -249,14 +236,13 @@ namespace pmon::tel::uci } std::lock_guard dataLock{ dataMutex_ }; - ValidateMetricIndex_(device_, metricId, arrayIndex); + ValidateMetricIndex_(systemDevice_, metricId, arrayIndex); switch (metricId) { case PM_METRIC_CPU_POWER: - return device_.samples.hasCpuPower ? device_.samples.cpuPower : 0.0; + return systemDevice_.cpuPowerSample.value_or(0.0); case PM_METRIC_CPU_TEMPERATURE: - return device_.samples.hasCpuTemperature[arrayIndex] ? - device_.samples.cpuTemperatures[arrayIndex] : 0.0; + return systemDevice_.cpuCoreTemperaturesSample[arrayIndex].value_or(0.0); default: throw Except<>("Unsupported metric for UCI provider"); } @@ -277,16 +263,28 @@ namespace pmon::tel::uci void UciTelemetryProvider::SetMetricUse(const svc::DeviceMetricUse& metricUse) { std::lock_guard configLock{ configMutex_ }; - std::unordered_set systemMetricUse; + bool wantsCpuPower = false; + bool wantsCpuTemperature = false; if (const auto it = metricUse.find(ipc::kSystemDeviceId); it != metricUse.end()) { - systemMetricUse = it->second; + for (const auto& use : it->second) { + if (use.metricId == PM_METRIC_CPU_POWER && + systemDevice_.caps.Check(PM_METRIC_CPU_POWER) != 0) { + wantsCpuPower = true; + } + else if (use.metricId == PM_METRIC_CPU_TEMPERATURE && + systemDevice_.caps.Check(PM_METRIC_CPU_TEMPERATURE) != 0) { + wantsCpuTemperature = true; + } + } } - if (metricUse_ == systemMetricUse) { + if (wantsCpuPower_ == wantsCpuPower && + wantsCpuTemperature_ == wantsCpuTemperature) { return; } - metricUse_ = std::move(systemMetricUse); + wantsCpuPower_ = wantsCpuPower; + wantsCpuTemperature_ = wantsCpuTemperature; ReconfigureCollection_(); } @@ -295,6 +293,9 @@ namespace pmon::tel::uci if (auto* pProvider = activeProvider_.load(std::memory_order_acquire)) { pProvider->OnDataCallback_(dataBundle); } + else { + pmlog_warn("UCI callback fired with no provider set").every(10s); + } } uint32_t UciTelemetryProvider::CountPhysicalCores_() @@ -302,7 +303,7 @@ namespace pmon::tel::uci DWORD bytes = 0; GetLogicalProcessorInformationEx(RelationProcessorCore, nullptr, &bytes); if (GetLastError() != ERROR_INSUFFICIENT_BUFFER || bytes == 0) { - return 1; + return 0; } std::vector buffer(bytes); @@ -310,7 +311,7 @@ namespace pmon::tel::uci RelationProcessorCore, (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)buffer.data(), &bytes)) { - return 1; + return 0; } uint32_t coreCount = 0; @@ -323,7 +324,7 @@ namespace pmon::tel::uci offset += pInfo->Size; } - return coreCount != 0 ? coreCount : 1; + return coreCount; } void UciTelemetryProvider::ValidateMetricIndex_( @@ -338,7 +339,7 @@ namespace pmon::tel::uci } return; case PM_METRIC_CPU_TEMPERATURE: - if (arrayIndex >= device.samples.cpuTemperatures.size()) { + if (arrayIndex >= device.cpuCoreTemperaturesSample.size()) { throw Except<>("UCI CPU temperature queried with out-of-range array index"); } return; @@ -362,8 +363,9 @@ namespace pmon::tel::uci if (enumeratedMetricNames.contains(std::string{ kCpuPowerMetricName_ })) { caps.Set(PM_METRIC_CPU_POWER, 1); } - if (enumeratedMetricNames.contains(std::string{ kCpuTemperatureMetricName_ })) { - caps.Set(PM_METRIC_CPU_TEMPERATURE, physicalCoreCount != 0 ? physicalCoreCount : 1); + if (physicalCoreCount != 0 && + enumeratedMetricNames.contains(std::string{ kCpuTemperatureMetricName_ })) { + caps.Set(PM_METRIC_CPU_TEMPERATURE, physicalCoreCount); } return caps; } @@ -398,13 +400,12 @@ namespace pmon::tel::uci void UciTelemetryProvider::DumpMetricEnumeration_(uciMetricContainerHandle metricContainer) const { - std::ostringstream oss; - oss << "UCI metric enumeration dump\n"; + std::string dump = "UCI metric enumeration dump\n"; uint32_t metricCount = 0; uciMetricHandle* pMetrics = nullptr; auto result = uciGetMetricContainerMetrics(metricContainer, &metricCount, &pMetrics); - oss << "metrics.result=" << (int)result << " metrics.count=" << metricCount << '\n'; + dump += std::format("metrics.result={} metrics.count={}\n", (int)result, metricCount); if (result == UC_SUCCESS && pMetrics != nullptr) { for (uint32_t i = 0; i < metricCount; ++i) { uint32_t metricId = 0; @@ -413,7 +414,7 @@ namespace pmon::tel::uci auto metricIdResult = uciGetMetricId(pMetrics[i], &metricId); TryGetString_(uciGetMetricName, pMetrics[i], metricName); TryGetString_(uciGetMetricDescription, pMetrics[i], metricDescription); - oss << std::format( + dump += std::format( "metric[{}] id.result={} id={} name=\"{}\" description=\"{}\"\n", i, (int)metricIdResult, @@ -424,7 +425,7 @@ namespace pmon::tel::uci uint32_t eventCount = 0; uciMetricEventHandle* pEvents = nullptr; auto eventResult = uciGetMetricEvents(pMetrics[i], &eventCount, &pEvents); - oss << std::format( + dump += std::format( "metric[{}].events.result={} metric[{}].events.count={}\n", i, (int)eventResult, @@ -438,7 +439,7 @@ namespace pmon::tel::uci auto eventIdResult = uciGetEventId(pEvents[j], &eventId); TryGetString_(uciGetMetricEventName, pEvents[j], eventName); TryGetString_(uciGetMetricEventDescription, pEvents[j], eventDescription); - oss << std::format( + dump += std::format( "metric[{}].event[{}] id.result={} id={} name=\"{}\" description=\"{}\"\n", i, j, @@ -454,7 +455,7 @@ namespace pmon::tel::uci uint32_t groupCount = 0; uciMetricGroupHandle* pGroups = nullptr; result = uciGetMetricContainerGroups(metricContainer, &groupCount, &pGroups); - oss << "groups.result=" << (int)result << " groups.count=" << groupCount << '\n'; + dump += std::format("groups.result={} groups.count={}\n", (int)result, groupCount); if (result == UC_SUCCESS && pGroups != nullptr) { for (uint32_t i = 0; i < groupCount; ++i) { uint32_t groupId = 0; @@ -463,7 +464,7 @@ namespace pmon::tel::uci auto groupIdResult = uciGetMetricGroupId(pGroups[i], &groupId); TryGetString_(uciGetMetricGroupName, pGroups[i], groupName); TryGetString_(uciGetMetricGroupDescription, pGroups[i], groupDescription); - oss << std::format( + dump += std::format( "group[{}] id.result={} id={} name=\"{}\" description=\"{}\"\n", i, (int)groupIdResult, @@ -475,7 +476,7 @@ namespace pmon::tel::uci uciMetricHandle* pGroupMetrics = nullptr; auto groupMetricResult = uciGetMetricsInGroup(pGroups[i], &groupMetricCount, &pGroupMetrics); - oss << std::format( + dump += std::format( "group[{}].metrics.result={} group[{}].metrics.count={}\n", i, (int)groupMetricResult, @@ -487,7 +488,7 @@ namespace pmon::tel::uci std::string groupMetricDescription; TryGetString_(uciGetMetricName, pGroupMetrics[j], groupMetricName); TryGetString_(uciGetMetricDescription, pGroupMetrics[j], groupMetricDescription); - oss << std::format( + dump += std::format( "group[{}].metric[{}] name=\"{}\" description=\"{}\"\n", i, j, @@ -504,8 +505,10 @@ namespace pmon::tel::uci metricContainer, &containerEventCount, &pContainerEvents); - oss << "container.events.result=" << (int)result - << " container.events.count=" << containerEventCount << '\n'; + dump += std::format( + "container.events.result={} container.events.count={}\n", + (int)result, + containerEventCount); if (result == UC_SUCCESS && pContainerEvents != nullptr) { for (uint32_t i = 0; i < containerEventCount; ++i) { uint32_t eventId = 0; @@ -514,7 +517,7 @@ namespace pmon::tel::uci auto eventIdResult = uciGetEventId(pContainerEvents[i], &eventId); TryGetString_(uciGetMetricEventName, pContainerEvents[i], eventName); TryGetString_(uciGetMetricEventDescription, pContainerEvents[i], eventDescription); - oss << std::format( + dump += std::format( "container.event[{}] id.result={} id={} name=\"{}\" description=\"{}\"\n", i, (int)eventIdResult, @@ -524,7 +527,7 @@ namespace pmon::tel::uci } } - pmlog_verb(v::uci)(oss.str()); + pmlog_verb(v::uci)(dump); } void UciTelemetryProvider::OnDataCallback_(uciDataBundle* dataBundle) @@ -539,7 +542,7 @@ namespace pmon::tel::uci std::lock_guard dataLock{ dataMutex_ }; for (uint16_t i = 0; i < dataBundle->numRecords; ++i) { - ApplyMetricRecord_(device_, dataBundle->records[i]); + ApplyMetricRecord_(systemDevice_, dataBundle->records[i]); } } @@ -553,14 +556,14 @@ namespace pmon::tel::uci } double sample = 0.0; - if (!TryGetSample_(uciMetricRecordGetSample, record, sample)) { + if (uciMetricRecordGetSample(record, &sample) != UC_SUCCESS) { pmlog_dbg("Could not get record sample"); return; } if (metricName == kCpuPowerRecordMetricName_) { uint64_t duration = 0; - if (!TryGetDuration_(uciMetricRecordGetRecordDuration, record, duration) || duration == 0) { + if (uciMetricRecordGetRecordDuration(record, &duration) != UC_SUCCESS || duration == 0) { pmlog_dbg("Could not get record duration"); return; } @@ -571,47 +574,34 @@ namespace pmon::tel::uci return; } - device.samples.cpuPower = (sample / durationSeconds) / 1000.0; - device.samples.hasCpuPower = true; + device.cpuPowerSample = (sample / durationSeconds) / 1000.0; return; } std::string entity; TryGetString_(uciMetricRecordGetEntity, record, entity); - if (!IsCpuTemperatureRecord_(metricName, entity)) { + if (metricName != kCpuTemperatureRecordMetricName_) { return; } if (const auto coreIndex = TryParseCoreIndex_(entity)) { - if (*coreIndex < device.samples.cpuTemperatures.size()) { - device.samples.cpuTemperatures[*coreIndex] = sample; - device.samples.hasCpuTemperature[*coreIndex] = true; + if (*coreIndex < device.cpuCoreTemperaturesSample.size()) { + device.cpuCoreTemperaturesSample[*coreIndex] = sample; } - return; } - + return; } void UciTelemetryProvider::ReconfigureCollection_() { if (!collector_) { + pmlog_error("no collector"); return; } - bool wantsCpuPower = false; - bool wantsCpuTemperature = false; - for (const auto& use : metricUse_) { - if (use.metricId == PM_METRIC_CPU_POWER && - enumeratedMetricNames_.contains(std::string{ kCpuPowerMetricName_ })) { - wantsCpuPower = true; - } - else if (use.metricId == PM_METRIC_CPU_TEMPERATURE && - enumeratedMetricNames_.contains(std::string{ kCpuTemperatureMetricName_ })) { - wantsCpuTemperature = true; - } - } - + const auto wantsCpuPower = wantsCpuPower_; + const auto wantsCpuTemperature = wantsCpuTemperature_; const bool wantsCollection = wantsCpuPower || wantsCpuTemperature; pmlog_dbg(std::format( "Configuring UCI collection; pollRateMs={} wantsCpuPower={} wantsCpuTemperature={} collectionStarted={}", @@ -624,10 +614,11 @@ namespace pmon::tel::uci pmlog_dbg("Stopping UCI collection because no supported UCI metrics are requested"); StopCollection_(); std::lock_guard dataLock{ dataMutex_ }; - device_.samples.cpuPower = 0.0; - device_.samples.hasCpuPower = false; - std::fill(device_.samples.cpuTemperatures.begin(), device_.samples.cpuTemperatures.end(), 0.0); - std::fill(device_.samples.hasCpuTemperature.begin(), device_.samples.hasCpuTemperature.end(), false); + systemDevice_.cpuPowerSample.reset(); + std::fill( + systemDevice_.cpuCoreTemperaturesSample.begin(), + systemDevice_.cpuCoreTemperaturesSample.end(), + std::nullopt); return; } diff --git a/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.h b/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.h index 93ca8dcc..612ae9de 100644 --- a/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.h +++ b/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -33,21 +34,14 @@ namespace pmon::tel::uci void SetMetricUse(const svc::DeviceMetricUse& metricUse) override; private: - struct SampleState_ - { - double cpuPower = 0.0; - bool hasCpuPower = false; - std::vector cpuTemperatures{}; - std::vector hasCpuTemperature{}; - }; - struct DeviceState_ { ProviderDeviceId providerDeviceId = 0; TelemetryDeviceFingerprint fingerprint{}; ipc::MetricCapabilities caps{}; uint32_t physicalCoreCount = 1; - SampleState_ samples{}; + std::optional cpuPowerSample{}; + std::vector> cpuCoreTemperaturesSample{}; }; static void StaticDataCallback_(uciDataBundle* dataBundle); @@ -68,13 +62,13 @@ namespace pmon::tel::uci private: static constexpr ProviderDeviceId kProviderDeviceId_ = 1; uciCollectorHandle collector_ = nullptr; - DeviceState_ device_{}; + DeviceState_ systemDevice_{}; std::mutex configMutex_{}; std::mutex dataMutex_{}; - std::unordered_set metricUse_{}; - std::unordered_set enumeratedMetricNames_{}; uint32_t pollRateMs_ = 1000; bool collectionStarted_ = false; + bool wantsCpuPower_ = false; + bool wantsCpuTemperature_ = false; static std::atomic activeProvider_; }; From 88c6d09c4a1fd6d0ed3938164e9500ab87b5d4ec Mon Sep 17 00:00:00 2001 From: Chili Date: Fri, 20 Mar 2026 13:16:28 +0900 Subject: [PATCH 26/42] per core and all core cpu temperature --- .../ControlLib/uci/UciTelemetryProvider.cpp | 51 +++++++++++++++---- .../ControlLib/uci/UciTelemetryProvider.h | 2 + .../Interprocess/source/metadata/MetricList.h | 1 + .../PresentMonAPI2/PresentMonAPI.h | 3 +- IntelPresentMon/metrics.csv | 3 +- 5 files changed, 49 insertions(+), 11 deletions(-) diff --git a/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp b/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp index 2f49dbfc..9319eabe 100644 --- a/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp @@ -242,6 +242,8 @@ namespace pmon::tel::uci case PM_METRIC_CPU_POWER: return systemDevice_.cpuPowerSample.value_or(0.0); case PM_METRIC_CPU_TEMPERATURE: + return ComputeAverageCpuTemperature_(systemDevice_).value_or(0.0); + case PM_METRIC_CPU_CORE_TEMPERATURE: return systemDevice_.cpuCoreTemperaturesSample[arrayIndex].value_or(0.0); default: throw Except<>("Unsupported metric for UCI provider"); @@ -265,6 +267,7 @@ namespace pmon::tel::uci std::lock_guard configLock{ configMutex_ }; bool wantsCpuPower = false; bool wantsCpuTemperature = false; + bool wantsCpuCoreTemperature = false; if (const auto it = metricUse.find(ipc::kSystemDeviceId); it != metricUse.end()) { for (const auto& use : it->second) { if (use.metricId == PM_METRIC_CPU_POWER && @@ -275,16 +278,22 @@ namespace pmon::tel::uci systemDevice_.caps.Check(PM_METRIC_CPU_TEMPERATURE) != 0) { wantsCpuTemperature = true; } + else if (use.metricId == PM_METRIC_CPU_CORE_TEMPERATURE && + systemDevice_.caps.Check(PM_METRIC_CPU_CORE_TEMPERATURE) != 0) { + wantsCpuCoreTemperature = true; + } } } if (wantsCpuPower_ == wantsCpuPower && - wantsCpuTemperature_ == wantsCpuTemperature) { + wantsCpuTemperature_ == wantsCpuTemperature && + wantsCpuCoreTemperature_ == wantsCpuCoreTemperature) { return; } wantsCpuPower_ = wantsCpuPower; wantsCpuTemperature_ = wantsCpuTemperature; + wantsCpuCoreTemperature_ = wantsCpuCoreTemperature; ReconfigureCollection_(); } @@ -327,6 +336,25 @@ namespace pmon::tel::uci return coreCount; } + std::optional UciTelemetryProvider::ComputeAverageCpuTemperature_(const DeviceState_& device) + { + double sum = 0.0; + uint32_t sampleCount = 0; + for (const auto& sample : device.cpuCoreTemperaturesSample) { + if (!sample) { + continue; + } + sum += *sample; + ++sampleCount; + } + + if (sampleCount == 0) { + return std::nullopt; + } + + return sum / (double)sampleCount; + } + void UciTelemetryProvider::ValidateMetricIndex_( const DeviceState_& device, PM_METRIC metricId, @@ -334,13 +362,14 @@ namespace pmon::tel::uci { switch (metricId) { case PM_METRIC_CPU_POWER: + case PM_METRIC_CPU_TEMPERATURE: if (arrayIndex != 0) { throw Except<>("UCI scalar metric queried with nonzero array index"); } return; - case PM_METRIC_CPU_TEMPERATURE: + case PM_METRIC_CPU_CORE_TEMPERATURE: if (arrayIndex >= device.cpuCoreTemperaturesSample.size()) { - throw Except<>("UCI CPU temperature queried with out-of-range array index"); + throw Except<>("UCI CPU core temperature queried with out-of-range array index"); } return; default: @@ -365,7 +394,8 @@ namespace pmon::tel::uci } if (physicalCoreCount != 0 && enumeratedMetricNames.contains(std::string{ kCpuTemperatureMetricName_ })) { - caps.Set(PM_METRIC_CPU_TEMPERATURE, physicalCoreCount); + caps.Set(PM_METRIC_CPU_TEMPERATURE, 1); + caps.Set(PM_METRIC_CPU_CORE_TEMPERATURE, physicalCoreCount); } return caps; } @@ -602,12 +632,14 @@ namespace pmon::tel::uci const auto wantsCpuPower = wantsCpuPower_; const auto wantsCpuTemperature = wantsCpuTemperature_; - const bool wantsCollection = wantsCpuPower || wantsCpuTemperature; + const auto wantsCpuCoreTemperature = wantsCpuCoreTemperature_; + const bool wantsCollection = wantsCpuPower || wantsCpuTemperature || wantsCpuCoreTemperature; pmlog_dbg(std::format( - "Configuring UCI collection; pollRateMs={} wantsCpuPower={} wantsCpuTemperature={} collectionStarted={}", + "Configuring UCI collection; pollRateMs={} wantsCpuPower={} wantsCpuTemperature={} wantsCpuCoreTemperature={} collectionStarted={}", pollRateMs_, wantsCpuPower, wantsCpuTemperature, + wantsCpuCoreTemperature, collectionStarted_)); if (!wantsCollection) { @@ -628,7 +660,7 @@ namespace pmon::tel::uci if (wantsCpuPower) { AppendQuotedMetricName_(metricsJson, kCpuPowerMetricName_); } - if (wantsCpuTemperature) { + if (wantsCpuTemperature || wantsCpuCoreTemperature) { AppendQuotedMetricName_(metricsJson, kCpuTemperatureMetricName_); } @@ -670,10 +702,11 @@ namespace pmon::tel::uci } pmlog_dbg(std::format( - "Starting UCI collection; pollRateMs={} wantsCpuPower={} wantsCpuTemperature={}", + "Starting UCI collection; pollRateMs={} wantsCpuPower={} wantsCpuTemperature={} wantsCpuCoreTemperature={}", pollRateMs_, wantsCpuPower, - wantsCpuTemperature)); + wantsCpuTemperature, + wantsCpuCoreTemperature)); CheckUciCall_(uciStartCollection(collector_), "uciStartCollection"); collectionStarted_ = true; } diff --git a/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.h b/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.h index 612ae9de..230fec7f 100644 --- a/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.h +++ b/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.h @@ -46,6 +46,7 @@ namespace pmon::tel::uci static void StaticDataCallback_(uciDataBundle* dataBundle); static uint32_t CountPhysicalCores_(); + static std::optional ComputeAverageCpuTemperature_(const DeviceState_& device); static void ValidateMetricIndex_(const DeviceState_& device, PM_METRIC metricId, uint32_t arrayIndex); static TelemetryDeviceFingerprint BuildFingerprint_(); static ipc::MetricCapabilities BuildCaps_( @@ -69,6 +70,7 @@ namespace pmon::tel::uci bool collectionStarted_ = false; bool wantsCpuPower_ = false; bool wantsCpuTemperature_ = false; + bool wantsCpuCoreTemperature_ = false; static std::atomic activeProvider_; }; diff --git a/IntelPresentMon/Interprocess/source/metadata/MetricList.h b/IntelPresentMon/Interprocess/source/metadata/MetricList.h index a6900711..c39a5598 100644 --- a/IntelPresentMon/Interprocess/source/metadata/MetricList.h +++ b/IntelPresentMon/Interprocess/source/metadata/MetricList.h @@ -70,6 +70,7 @@ X_(PM_METRIC_CPU_POWER_LIMIT, PM_METRIC_TYPE_STATIC, PM_UNIT_WATTS, PM_DATA_TYPE_DOUBLE, PM_DATA_TYPE_DOUBLE, 0, PM_DEVICE_TYPE_SYSTEM, PM_STAT_NONE) \ X_(PM_METRIC_CPU_POWER, PM_METRIC_TYPE_DYNAMIC_FRAME, PM_UNIT_WATTS, PM_DATA_TYPE_DOUBLE, PM_DATA_TYPE_DOUBLE, 0, PM_DEVICE_TYPE_SYSTEM, FULL_STATS) \ X_(PM_METRIC_CPU_TEMPERATURE, PM_METRIC_TYPE_DYNAMIC_FRAME, PM_UNIT_CELSIUS, PM_DATA_TYPE_DOUBLE, PM_DATA_TYPE_DOUBLE, 0, PM_DEVICE_TYPE_SYSTEM, FULL_STATS) \ + X_(PM_METRIC_CPU_CORE_TEMPERATURE, PM_METRIC_TYPE_DYNAMIC_FRAME, PM_UNIT_CELSIUS, PM_DATA_TYPE_DOUBLE, PM_DATA_TYPE_DOUBLE, 0, PM_DEVICE_TYPE_SYSTEM, FULL_STATS) \ X_(PM_METRIC_CPU_FREQUENCY, PM_METRIC_TYPE_DYNAMIC_FRAME, PM_UNIT_MEGAHERTZ, PM_DATA_TYPE_DOUBLE, PM_DATA_TYPE_DOUBLE, 0, PM_DEVICE_TYPE_SYSTEM, FULL_STATS) \ X_(PM_METRIC_CPU_CORE_UTILITY, PM_METRIC_TYPE_DYNAMIC, PM_UNIT_PERCENT, PM_DATA_TYPE_DOUBLE, PM_DATA_TYPE_DOUBLE, 0, PM_DEVICE_TYPE_SYSTEM, FULL_STATS) \ X_(PM_METRIC_ALL_INPUT_TO_PHOTON_LATENCY, PM_METRIC_TYPE_DYNAMIC_FRAME, PM_UNIT_MILLISECONDS, PM_DATA_TYPE_DOUBLE, PM_DATA_TYPE_DOUBLE, 0, PM_DEVICE_TYPE_INDEPENDENT, PM_STAT_NON_ZERO_AVG, PM_STAT_PERCENTILE_01, PM_STAT_PERCENTILE_05, PM_STAT_PERCENTILE_10, PM_STAT_MAX) \ diff --git a/IntelPresentMon/PresentMonAPI2/PresentMonAPI.h b/IntelPresentMon/PresentMonAPI2/PresentMonAPI.h index 63b538f7..8fc715fd 100644 --- a/IntelPresentMon/PresentMonAPI2/PresentMonAPI.h +++ b/IntelPresentMon/PresentMonAPI2/PresentMonAPI.h @@ -10,7 +10,7 @@ #include #define PM_API_VERSION_MAJOR 3 -#define PM_API_VERSION_MINOR 3 +#define PM_API_VERSION_MINOR 4 #define PM_MAX_PATH 260 @@ -140,6 +140,7 @@ extern "C" { PM_METRIC_FLIP_DELAY, PM_METRIC_PROCESS_ID, PM_METRIC_SESSION_START_QPC, + PM_METRIC_CPU_CORE_TEMPERATURE, PM_METRIC_COUNT_, // sentry to mark end of metric list; not an actual query metric }; diff --git a/IntelPresentMon/metrics.csv b/IntelPresentMon/metrics.csv index ffdd5397..3ee493e1 100644 --- a/IntelPresentMon/metrics.csv +++ b/IntelPresentMon/metrics.csv @@ -78,7 +78,8 @@ PM_METRIC_GPU_MEM_UTILIZATION_LIMITED,1,GPU Memory Utilization Limited,Memory fr PM_METRIC_CPU_UTILIZATION,1,CPU Utilization,Amount of CPU processing capacity being used. PM_METRIC_CPU_POWER_LIMIT,1,CPU Power Limit,Power limit of the CPU. PM_METRIC_CPU_POWER,1,CPU Power,Power consumed by the CPU. -PM_METRIC_CPU_TEMPERATURE,1,CPU Temperature,Temperature of each physical CPU core. +PM_METRIC_CPU_TEMPERATURE,1,CPU Temperature,Average temperature across all physical CPU cores with available temperature samples. +PM_METRIC_CPU_CORE_TEMPERATURE,1,CPU Core Temperature,Temperature of each physical CPU core. PM_METRIC_CPU_FREQUENCY,1,CPU Frequency,Clock speed of the CPU. PM_METRIC_CPU_CORE_UTILITY,1,CPU Core Utility,Amount of CPU processing utility being used per core. ,,, From c147b32ccf1b2b32ac9d769c6af744c0db1f8f1e Mon Sep 17 00:00:00 2001 From: "Taylor, Raymond" Date: Fri, 20 Mar 2026 15:07:29 +0900 Subject: [PATCH 27/42] update uci to fix collection lifecycle bug --- IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp b/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp index 9319eabe..e07d7bfc 100644 --- a/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp +++ b/IntelPresentMon/ControlLib/uci/UciTelemetryProvider.cpp @@ -87,13 +87,13 @@ namespace pmon::tel::uci std::string dump = std::format( "UCI callback received numRecords={}\n", - dataBundle->numRecords); + dataBundle->num_records); if (dataBundle->records == nullptr) { pmlog_verb(v::uci)("records array pointer is null"); return; } - for (uint16_t i = 0; i < dataBundle->numRecords; ++i) { + for (uint16_t i = 0; i < dataBundle->num_records; ++i) { const auto record = dataBundle->records[i]; dump += std::format("record[{}]\n", i); if (record == nullptr) { @@ -566,12 +566,12 @@ namespace pmon::tel::uci DumpDataCallback_(dataBundle); } - if (dataBundle == nullptr || dataBundle->records == nullptr || dataBundle->numRecords == 0) { + if (dataBundle == nullptr || dataBundle->records == nullptr || dataBundle->num_records == 0) { return; } std::lock_guard dataLock{ dataMutex_ }; - for (uint16_t i = 0; i < dataBundle->numRecords; ++i) { + for (uint16_t i = 0; i < dataBundle->num_records; ++i) { ApplyMetricRecord_(systemDevice_, dataBundle->records[i]); } } From d99f34bc24cfaa36dd7951e8f2b867e3da24d04d Mon Sep 17 00:00:00 2001 From: Chili Date: Sun, 22 Mar 2026 14:28:52 +0900 Subject: [PATCH 28/42] remove legacy getters/action --- .../ControlLib/TelemetryCoordinator.cpp | 39 -------------- .../ControlLib/TelemetryCoordinator.h | 10 ---- IntelPresentMon/Core/source/pmon/PresentMon.h | 1 - .../PresentMonService/AllActions.h | 3 +- .../PresentMonService/PMMainThread.cpp | 3 -- .../PresentMonService/PresentMon.h | 6 --- .../PresentMonService.vcxproj | 1 - .../PresentMonService.vcxproj.filters | 1 - .../PresentMonService/PresentMonSession.cpp | 13 ----- .../PresentMonService/PresentMonSession.h | 5 -- .../acts/GetStaticCpuMetrics.h | 51 ------------------- 11 files changed, 1 insertion(+), 132 deletions(-) delete mode 100644 IntelPresentMon/PresentMonService/acts/GetStaticCpuMetrics.h diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp index c7d57f96..80ed4e7b 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.cpp @@ -61,45 +61,6 @@ namespace pmon::tel BuildLogicalDevicesAndRoutes_(); } - std::optional TelemetryCoordinator::GetCpuInfo() const - { - const auto iLogicalDevice = logicalDevicesById_.find(ipc::kSystemDeviceId); - if (iLogicalDevice == logicalDevicesById_.end()) { - return std::nullopt; - } - - const auto requestQpc = util::GetCurrentTimestamp(); - const auto& logicalDevice = iLogicalDevice->second; - - CpuInfo cpuInfo{}; - const auto fingerprint = ResolveLogicalDeviceFingerprint_(logicalDevice); - cpuInfo.vendor = fingerprint.vendor; - if (!fingerprint.deviceName.empty()) { - cpuInfo.name = fingerprint.deviceName; - } - else { - cpuInfo.name = "UNKNOWN_CPU"; - } - - if (logicalDevice.routes.contains(PM_METRIC_CPU_POWER_LIMIT)) { - try { - const auto value = PollMetricForRoute_(logicalDevice, PM_METRIC_CPU_POWER_LIMIT, 0, requestQpc); - if (const auto pVal = std::get_if(&value)) { - cpuInfo.cpuPowerLimit = *pVal; - } - else { - throw util::Except<>("Type mismatch while enumerating CPU static metric"); - } - } - catch (...) { - pmlog_error(util::ReportException("CPU static metric query failed")) - .pmwatch((int)PM_METRIC_CPU_POWER_LIMIT); - } - } - - return cpuInfo; - } - std::vector TelemetryCoordinator::EnumerateAdapters() const { std::vector adapters; diff --git a/IntelPresentMon/ControlLib/TelemetryCoordinator.h b/IntelPresentMon/ControlLib/TelemetryCoordinator.h index cdab4362..72f3ab6f 100644 --- a/IntelPresentMon/ControlLib/TelemetryCoordinator.h +++ b/IntelPresentMon/ControlLib/TelemetryCoordinator.h @@ -5,7 +5,6 @@ #include "../PresentMonService/MetricUse.h" #include "TelemetryProvider.h" #include -#include #include #include #include @@ -21,13 +20,6 @@ namespace pmon::tel class TelemetryCoordinator { public: - struct CpuInfo - { - PM_DEVICE_VENDOR vendor = PM_DEVICE_VENDOR_UNKNOWN; - std::string name{}; - double cpuPowerLimit = 0.0; - }; - struct AdapterInfo { uint32_t id = 0; @@ -41,8 +33,6 @@ namespace pmon::tel // Constructs all known concrete providers, correlates logical devices, // and builds metric polling routes. explicit TelemetryCoordinator(uint32_t pollRateMs); - // Returns system CPU static identity and routed static telemetry when present. - std::optional GetCpuInfo() const; // Returns GPU adapter identity and routed static telemetry for legacy service enumeration. std::vector EnumerateAdapters() const; // Registers logical CPU/GPU devices and per-device routed capabilities with IPC. diff --git a/IntelPresentMon/Core/source/pmon/PresentMon.h b/IntelPresentMon/Core/source/pmon/PresentMon.h index cda36ef1..40052d94 100644 --- a/IntelPresentMon/Core/source/pmon/PresentMon.h +++ b/IntelPresentMon/Core/source/pmon/PresentMon.h @@ -33,7 +33,6 @@ namespace p2c::pmon uint32_t GetGpuTelemetryPeriod(); void SetEtwFlushPeriod(std::optional periodMs); std::optional GetEtwFlushPeriod(); - // std::wstring GetCpuName() const; std::vector EnumerateAdapters() const; void SetEtlLogging(bool active); std::optional GetPid() const; diff --git a/IntelPresentMon/PresentMonService/AllActions.h b/IntelPresentMon/PresentMonService/AllActions.h index e2fad16c..59c4054f 100644 --- a/IntelPresentMon/PresentMonService/AllActions.h +++ b/IntelPresentMon/PresentMonService/AllActions.h @@ -2,9 +2,7 @@ #pragma once #include "acts/EnumerateAdapters.h" #include "acts/FinishEtlLogging.h" -#include "acts/GetStaticCpuMetrics.h" #include "acts/OpenSession.h" -#include "acts/ReportFrameReadProgress.h" #include "acts/ReportMetricUse.h" #include "acts/SetEtwFlushPeriod.h" #include "acts/SetTelemetryPeriod.h" @@ -12,3 +10,4 @@ #include "acts/StartTracking.h" #include "acts/StopPlayback.h" #include "acts/StopTracking.h" +#include "acts/ReportFrameReadProgress.h" diff --git a/IntelPresentMon/PresentMonService/PMMainThread.cpp b/IntelPresentMon/PresentMonService/PMMainThread.cpp index 3edb5ec0..f7e21cbf 100644 --- a/IntelPresentMon/PresentMonService/PMMainThread.cpp +++ b/IntelPresentMon/PresentMonService/PMMainThread.cpp @@ -130,9 +130,6 @@ void TelemetryThreadEntry_(Service* const srv, PresentMon* const pm, ipc::Servic pmon::tel::TelemetryCoordinator coordinator{ pm->GetGpuTelemetryPeriod() }; coordinator.RegisterDevicesToIpc(*pComms); coordinator.PopulateStaticsToIpc(*pComms); - if (const auto cpuInfo = coordinator.GetCpuInfo()) { - pm->SetCpuStaticInfo(cpuInfo->name, cpuInfo->cpuPowerLimit); - } pm->SetTelemetryAdapters(coordinator.EnumerateAdapters()); pmlog_info(std::format( "Finished populating telemetry introspection, {} seconds elapsed", diff --git a/IntelPresentMon/PresentMonService/PresentMon.h b/IntelPresentMon/PresentMonService/PresentMon.h index e6f69dd0..89054893 100644 --- a/IntelPresentMon/PresentMonService/PresentMon.h +++ b/IntelPresentMon/PresentMonService/PresentMon.h @@ -38,8 +38,6 @@ class PresentMon void StopTraceSessions(); PM_STATUS UpdateTracking(const std::unordered_set& trackedPids); std::vector EnumerateAdapters() const; - std::string GetCpuName() { return pSession_->GetCpuName(); } - double GetCpuPowerLimit() { return pSession_->GetCpuPowerLimit(); } PM_STATUS SetGpuTelemetryPeriod(std::optional telemetryPeriodRequestsMs) { return pSession_->SetGpuTelemetryPeriod(telemetryPeriodRequestsMs); @@ -59,10 +57,6 @@ class PresentMon // Only the real time trace sets ETW flush period return pSession_->GetEtwFlushPeriod(); } - void SetCpuStaticInfo(std::string cpuName, double cpuPowerLimit) - { - pSession_->SetCpuStaticInfo(std::move(cpuName), cpuPowerLimit); - } HANDLE GetStreamingStartHandle() { return pSession_->GetStreamingStartHandle(); diff --git a/IntelPresentMon/PresentMonService/PresentMonService.vcxproj b/IntelPresentMon/PresentMonService/PresentMonService.vcxproj index e59482eb..38293e54 100644 --- a/IntelPresentMon/PresentMonService/PresentMonService.vcxproj +++ b/IntelPresentMon/PresentMonService/PresentMonService.vcxproj @@ -132,7 +132,6 @@ - diff --git a/IntelPresentMon/PresentMonService/PresentMonService.vcxproj.filters b/IntelPresentMon/PresentMonService/PresentMonService.vcxproj.filters index cba62482..74678b5c 100644 --- a/IntelPresentMon/PresentMonService/PresentMonService.vcxproj.filters +++ b/IntelPresentMon/PresentMonService/PresentMonService.vcxproj.filters @@ -32,7 +32,6 @@ - diff --git a/IntelPresentMon/PresentMonService/PresentMonSession.cpp b/IntelPresentMon/PresentMonService/PresentMonSession.cpp index d2ece4c8..43c4f63d 100644 --- a/IntelPresentMon/PresentMonService/PresentMonSession.cpp +++ b/IntelPresentMon/PresentMonService/PresentMonSession.cpp @@ -30,19 +30,6 @@ std::vector PresentMonSession::Enu return telemetry_adapters_; } -void PresentMonSession::SetCpuStaticInfo(std::string cpuName, double cpuPowerLimit) { - cpu_name_ = std::move(cpuName); - cpu_power_limit_ = cpuPowerLimit; -} - -std::string PresentMonSession::GetCpuName() { - return cpu_name_.empty() ? std::string{ "UNKOWN_CPU" } : cpu_name_; -} - -double PresentMonSession::GetCpuPowerLimit() { - return cpu_power_limit_; -} - PM_STATUS PresentMonSession::SetGpuTelemetryPeriod(std::optional period_ms) { gpu_telemetry_period_ms_ = period_ms.value_or(default_gpu_telemetry_period_ms_); diff --git a/IntelPresentMon/PresentMonService/PresentMonSession.h b/IntelPresentMon/PresentMonService/PresentMonSession.h index 7ef55e57..983e1359 100644 --- a/IntelPresentMon/PresentMonService/PresentMonSession.h +++ b/IntelPresentMon/PresentMonService/PresentMonSession.h @@ -40,9 +40,6 @@ class PresentMonSession { virtual void ResetEtwFlushPeriod() = 0; std::vector EnumerateAdapters() const; - void SetCpuStaticInfo(std::string cpuName, double cpuPowerLimit); - std::string GetCpuName(); - double GetCpuPowerLimit(); pmon::test::service::Status GetTestingStatus() const; PM_STATUS SetGpuTelemetryPeriod(std::optional period_ms); PM_STATUS SetEtwFlushPeriod(std::optional periodMs); @@ -63,8 +60,6 @@ class PresentMonSession { // data std::wstring pm_session_name_; - std::string cpu_name_{}; - double cpu_power_limit_ = 0.0; std::vector telemetry_adapters_{}; // Set the initial telemetry period to 16ms diff --git a/IntelPresentMon/PresentMonService/acts/GetStaticCpuMetrics.h b/IntelPresentMon/PresentMonService/acts/GetStaticCpuMetrics.h deleted file mode 100644 index d648ae94..00000000 --- a/IntelPresentMon/PresentMonService/acts/GetStaticCpuMetrics.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once -#include "../../Interprocess/source/act/ActionHelper.h" -#include - -#define ACT_NAME GetStaticCpuMetrics -#define ACT_EXEC_CTX ActionExecutionContext -#define ACT_NS ::pmon::svc::acts -#define ACT_TYPE AsyncActionBase_ - -namespace pmon::svc::acts -{ - using namespace ipc::act; - - class ACT_NAME : public ACT_TYPE - { - public: - static constexpr const char* Identifier = STRINGIFY(ACT_NAME); - struct Params {}; - struct Response - { - std::string cpuName; - double cpuPowerLimit; - - template void serialize(A& ar) { - ar(cpuName, cpuPowerLimit); - } - }; - private: - friend class ACT_TYPE; - static Response Execute_(const ACT_EXEC_CTX& ctx, SessionContext& stx, Params&& in) - { - const Response out{ - .cpuName = ctx.pPmon->GetCpuName(), - .cpuPowerLimit = ctx.pPmon->GetCpuPowerLimit() - }; - pmlog_dbg(std::format("static CPU metrics gotten for {} @ {}W", out.cpuName, out.cpuPowerLimit)); - return out; - } - }; - -#ifdef PM_ASYNC_ACTION_REGISTRATION_ - ACTION_REG(); -#endif -} - -ACTION_TRAITS_DEF(); - -#undef ACT_NAME -#undef ACT_EXEC_CTX -#undef ACT_NS -#undef ACT_TYPE \ No newline at end of file From 721cd50eef69ab5a5416b47d12ab60df3e518d2d Mon Sep 17 00:00:00 2001 From: Chili Date: Sun, 22 Mar 2026 15:56:46 +0900 Subject: [PATCH 29/42] more unused actions --- .../AppCef/ipm-ui-vue/src/core/api.ts | 11 +-- IntelPresentMon/AppCef/ipm-ui-vue/src/main.ts | 6 +- .../AppCef/ipm-ui-vue/src/stores/adapters.ts | 22 ------ .../ipm-ui-vue/src/stores/introspection.ts | 4 ++ .../ipm-ui-vue/src/views/DataConfigView.vue | 8 +-- .../source/util/KernelActionRegistration.cpp | 1 - .../ControlLib/TelemetryCoordinator.cpp | 66 ----------------- .../ControlLib/TelemetryCoordinator.h | 15 +--- IntelPresentMon/Core/Core.vcxproj | 3 +- IntelPresentMon/Core/Core.vcxproj.filters | 5 +- IntelPresentMon/Core/source/kernel/Kernel.cpp | 15 ---- IntelPresentMon/Core/source/kernel/Kernel.h | 1 - .../Core/source/pmon/AdapterInfo.h | 15 ---- .../Core/source/pmon/PresentMon.cpp | 15 ---- IntelPresentMon/Core/source/pmon/PresentMon.h | 2 - .../KernelProcess/KernelProcess.vcxproj | 3 +- .../KernelProcess.vcxproj.filters | 3 - .../KernelProcess/kact/AllActions.h | 1 - .../KernelProcess/kact/EnumerateAdapters.h | 58 --------------- .../KernelProcess/kact/Introspect.h | 27 ++++++- .../PresentMonService/AllActions.h | 23 +++--- .../PresentMonService/PMMainThread.cpp | 1 - .../PresentMonService/PresentMon.cpp | 5 -- .../PresentMonService/PresentMon.h | 5 -- .../PresentMonService.vcxproj | 1 - .../PresentMonService.vcxproj.filters | 1 - .../PresentMonService/PresentMonSession.cpp | 9 --- .../PresentMonService/PresentMonSession.h | 4 -- .../acts/EnumerateAdapters.h | 72 ------------------- .../PresentMonService/acts/FinishEtlLogging.h | 5 +- .../PresentMonService/acts/OpenSession.h | 5 +- .../PresentMonService/acts/ReportMetricUse.h | 1 + .../acts/SetEtwFlushPeriod.h | 3 +- .../acts/SetTelemetryPeriod.h | 3 +- .../PresentMonService/acts/StartEtlLogging.h | 5 +- .../PresentMonService/acts/StartTracking.h | 1 + .../PresentMonService/acts/StopPlayback.h | 5 +- .../PresentMonService/acts/StopTracking.h | 1 + 38 files changed, 73 insertions(+), 358 deletions(-) delete mode 100644 IntelPresentMon/AppCef/ipm-ui-vue/src/stores/adapters.ts delete mode 100644 IntelPresentMon/Core/source/pmon/AdapterInfo.h delete mode 100644 IntelPresentMon/KernelProcess/kact/EnumerateAdapters.h delete mode 100644 IntelPresentMon/PresentMonService/acts/EnumerateAdapters.h diff --git a/IntelPresentMon/AppCef/ipm-ui-vue/src/core/api.ts b/IntelPresentMon/AppCef/ipm-ui-vue/src/core/api.ts index 7a64534c..c0751757 100644 --- a/IntelPresentMon/AppCef/ipm-ui-vue/src/core/api.ts +++ b/IntelPresentMon/AppCef/ipm-ui-vue/src/core/api.ts @@ -54,10 +54,10 @@ export class Api { static async loadEnvVars(): Promise { return await this.invokeEndpointFuture('loadEnvVars', {}); } - static async introspect(): Promise<{metrics: Metric[], stats: Stat[], units: Unit[], systemDeviceId: number, defaultAdapterId: number}> { + static async introspect(): Promise<{metrics: Metric[], stats: Stat[], units: Unit[], adapters: Adapter[], systemDeviceId: number, defaultAdapterId: number}> { const introData = await this.invokeEndpointFuture('Introspect', {}); if (!Array.isArray(introData.metrics) || !Array.isArray(introData.stats) || - !Array.isArray(introData.units) || typeof introData.systemDeviceId !== 'number' || + !Array.isArray(introData.units) || !Array.isArray(introData.adapters) || typeof introData.systemDeviceId !== 'number' || typeof introData.defaultAdapterId !== 'number') { console.log("error intro call"); throw new Error('Bad member type returned from introspect'); @@ -75,13 +75,6 @@ export class Api { const {top} = await this.invokeEndpointFuture('getTopGpuProcess', {blacklist}); return top; } - static async enumerateAdapters(): Promise { - const {adapters} = await this.invokeEndpointFuture('EnumerateAdapters', {}); - if (!Array.isArray(adapters)) { - throw new Error('Bad (non-array) type returned from enumerateAdapters'); - } - return adapters; - } static async bindHotkey(binding: Binding): Promise { await this.invokeEndpointFuture('BindHotkey', binding); } diff --git a/IntelPresentMon/AppCef/ipm-ui-vue/src/main.ts b/IntelPresentMon/AppCef/ipm-ui-vue/src/main.ts index 3aaf97f0..08792274 100644 --- a/IntelPresentMon/AppCef/ipm-ui-vue/src/main.ts +++ b/IntelPresentMon/AppCef/ipm-ui-vue/src/main.ts @@ -1,4 +1,4 @@ -import '@/assets/global.css' +import '@/assets/global.css' import { createApp } from 'vue' import { createPinia } from 'pinia' @@ -17,7 +17,6 @@ import { md2 } from 'vuetify/blueprints' import { useHotkeyStore } from '@/stores/hotkey'; import { useIntrospectionStore } from '@/stores/introspection'; -import { useAdaptersStore } from './stores/adapters' import { loadBlocklists } from './core/block-list' import { usePreferencesStore } from './stores/preferences' @@ -100,7 +99,6 @@ async function initStores() { await Promise.all([ useHotkeyStore().refreshOptions(), useIntrospectionStore().load(), - useAdaptersStore().refresh(), loadBlocklists(), ]) await usePreferencesStore().initPreferences() @@ -117,4 +115,4 @@ async function boot() { app.mount('#app') } -boot() \ No newline at end of file +boot() diff --git a/IntelPresentMon/AppCef/ipm-ui-vue/src/stores/adapters.ts b/IntelPresentMon/AppCef/ipm-ui-vue/src/stores/adapters.ts deleted file mode 100644 index 0f5636e4..00000000 --- a/IntelPresentMon/AppCef/ipm-ui-vue/src/stores/adapters.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2022 Intel Corporation -// SPDX-License-Identifier: MIT -import { ref } from 'vue'; -import { defineStore } from 'pinia'; -import { Api } from '@/core/api'; -import type { Adapter } from '@/core/adapter'; - -export const useAdaptersStore = defineStore('adapters', () => { - // === State === - const adapters = ref([]); - - // === Actions === - async function refresh() { - adapters.value = await Api.enumerateAdapters(); - } - - // === Exports === - return { - adapters, - refresh, - }; -}); \ No newline at end of file diff --git a/IntelPresentMon/AppCef/ipm-ui-vue/src/stores/introspection.ts b/IntelPresentMon/AppCef/ipm-ui-vue/src/stores/introspection.ts index 6ee78c82..f1456a24 100644 --- a/IntelPresentMon/AppCef/ipm-ui-vue/src/stores/introspection.ts +++ b/IntelPresentMon/AppCef/ipm-ui-vue/src/stores/introspection.ts @@ -5,12 +5,14 @@ import type { Metric } from '@/core/metric'; import type { Stat } from '@/core/stat'; import type { Unit } from '@/core/unit'; import type { MetricOption } from '@/core/metric-option'; +import type { Adapter } from '@/core/adapter'; export const useIntrospectionStore = defineStore('introspection', () => { // === State === const metrics = ref([]); const stats = ref([]); const units = ref([]); + const adapters = ref([]); const systemDeviceId = ref(0); const defaultAdapterId = ref(0); @@ -32,6 +34,7 @@ export const useIntrospectionStore = defineStore('introspection', () => { metrics.value = intro.metrics; stats.value = intro.stats; units.value = intro.units; + adapters.value = intro.adapters; systemDeviceId.value = intro.systemDeviceId; defaultAdapterId.value = intro.defaultAdapterId; } @@ -42,6 +45,7 @@ export const useIntrospectionStore = defineStore('introspection', () => { metrics, stats, units, + adapters, systemDeviceId, defaultAdapterId, metricOptions, diff --git a/IntelPresentMon/AppCef/ipm-ui-vue/src/views/DataConfigView.vue b/IntelPresentMon/AppCef/ipm-ui-vue/src/views/DataConfigView.vue index ed3bc156..5e14f39e 100644 --- a/IntelPresentMon/AppCef/ipm-ui-vue/src/views/DataConfigView.vue +++ b/IntelPresentMon/AppCef/ipm-ui-vue/src/views/DataConfigView.vue @@ -1,14 +1,14 @@ - +