> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 动态电源状态(DPS)

> 启用动态电源状态,让 GPU 驱动根据渲染负载调节功耗,在 XBOX Series 主机上额外节省 10–15% 的能耗。

<Warning>
  DPS 仅在 **XBOX Series** 主机上可用。对更早的 XBOX 主机没有效果。
</Warning>

**动态电源状态(Dynamic Power States,DPS)** 会根据渲染负载动态调整 GPU 的功耗级别。当 GPU 未被完全利用时,DPS 会将电源状态回落 —— 在不牺牲性能的前提下节省能耗。图形驱动会依据近期的帧时间历史自动完成调整。

未启用 DPS 时,GPU 会锁定在电源状态 **P4** ,这意味着即使 GPU 空闲,也会消耗超过必要的电量。DPS 会在负载允许的情况下解锁更低的电源状态(P0–P3)。

## 工作原理

1. 游戏启用 GPU 动态电源状态。
2. GPU 计算归一化的帧统计数据并作为历史数据保存。
3. GPU 会根据当前需求和历史数据自动切换电源状态,节省能耗。

<Note>
  游戏可以进一步采用 [XBOX 可持续性工具包](/build/game-principles/sustainability/energy-efficiency-essentials) 中的其他措施,以进一步降低能耗。
</Note>

## 案例研究

### Call of Duty: Black Ops 6

Call of Duty 高级技术总监 Rulon Raymond:

> 我们花了几天时间试用 DPS,结果令人鼓舞。具体来说,我们在 XBOX 可持续性工具包**之外**的场景中,能看到**额外 10–15% 的功耗节省**。我们此前已经对游戏引擎的部分子系统做了降载(例如在菜单或前端界面时),对玩家的帧率没有影响,这已经为我们节省了大量能耗 —— 而 DPS 让我们能够零成本地获得额外收益。

在发布时,Black Ops 6 团队的计划:

* 在所有已经应用节能措施的位置启用 DPS。
* 提供一个默认关闭的开关来始终启用 DPS,同时继续进行多日性能测试。

### Two Point Museum

Two Point Studios 技术总监兼联合创始人 Ben Hymers 通过 XBOX 团队管理的云端设置发布了 DPS —— 无需修改代码:

> 我们把动态电源状态和 Constrained+ 模式一起测试,以最大化能效。两者结合后,**主菜单**的功耗降低了大约 **50–58%**,constrained 模式下的能耗降低了 **39–63%**。上线以来,我们观察到平均能耗有明显下降,而游戏画面没有任何降级。例如 XBOX Series X 的平均功耗从 **135 W 降到 125 W**。在我们的全部玩家中,这相当于每年节能约 **6.5 兆瓦时**,相当于连续观看电视 65,000 小时,或近 7.5 年不间断的观看。

Two Point Museum 是第一家通过云端配置远程启用 DPS 的第三方工作室。

## 无需修改代码测试 DPS(仅限开发环境)

你可以在开发主机上全局启用 DPS,而无需重新构建作品:

<Steps>
  <Step title="更新你的开发主机">
    确保开发主机安装了至少 **2024 年 8 月的 Recovery**。
  </Step>

  <Step title="创建标志文件">
    在你的 PC 上创建一个名为 `DynamicPowerEnable` 的空文件。
  </Step>

  <Step title="将其复制到主机的 D: 盘">
    ```sh theme={null}
    xbcp DynamicPowerEnable xD:\
    ```
  </Step>

  <Step title="启动并分析">
    启动你的游戏。DPS 现已生效。
  </Step>

  <Step title="使用完毕后禁用 DPS">
    ```sh theme={null}
    xbdel xD:\DynamicPowerEnable
    ```

    重新启动游戏。
  </Step>
</Steps>

### 实时观察 DPS

通过 PIX 或 XBOX Manager 中主机的设置启用 **Title Performance Overlay**。

* 如果 DPS 已启用,右下角的 overlay 会包含一条红线,以及 **GPU power state** 指标(0–4)。**4** 表示全速;数值越小代表越省电。
* 如果 DPS 已禁用,GPU power state 会显示为 `N/A`。

使用 PIX 的 **Power Load %** 指标可以衡量游戏各个部分 GPU 能耗的变化。

<Warning>
  在正式发布中,作品**不能**使用 `DynamicPowerEnable` 文件来启用 DPS。请在零售版中使用 `SetDriverHintX`(见下文)。
</Warning>

## 在你的游戏中启用 DPS(正式发布)

在图形设备上使用现有的 `SetDriverHintX()` API。

### API

```cpp theme={null}
SetDriverHintX(UINT feature, UINT value);
```

如果使用 **2024 年 6 月的 GDK** 或更新版本,可以使用枚举:

```cpp theme={null}
DRIVER_HINT_SET_DYNAMIC_POWER
```

对于 **2024 年 6 月之前的 GDK**(或较旧的 XDK 作品),直接使用数值:

```cpp theme={null}
0xEFF1C1E7
```

### 启用 DPS

```cpp theme={null}
SetDriverHintX(DRIVER_HINT_SET_DYNAMIC_POWER, 1);
// 或:
SetDriverHintX(0xEFF1C1E7, 1);
```

### 禁用 DPS

```cpp theme={null}
SetDriverHintX(DRIVER_HINT_SET_DYNAMIC_POWER, 0);
// 或:
SetDriverHintX(0xEFF1C1E7, 0);
```

DPS 可以在游戏运行时开关,但始终开启能获得最大节能收益。

<Warning>
  如果游戏会切换 DPS,请**在 PLM 的 `Resume()` 处理器中重置所需的值**。DPS 状态在 Suspend/Resume 之间不会保留。
</Warning>

## 通过帧统计在运行时检测 DPS

游戏可以查询帧统计,以根据 DPS 行为做出渲染决策(动态分辨率等)。

### GetFrameStatisticsX

新增了一种帧统计类型:

```cpp theme={null}
D3D12XBOX_FRAME_STATISTICS_TYPE_POWERSCALING
```

以及对应的结构体:

```cpp theme={null}
typedef struct D3D12XBOX_POWERSCALING_STATISTICS
{
    UINT8 PlaneIndex;
    UINT64 GPUBusyDurationScaled;
    double ScaleFactor;
} D3D12XBOX_POWERSCALING_STATISTICS;
```

现有的 `D3D12XBOX_RENDER_STATISTICS` 返回 `GPUBusyDuration`:

```cpp theme={null}
typedef struct D3D12XBOX_RENDER_STATISTICS
{
    UINT8 PlaneIndex;
    UINT64 GPUWriteCompleteTime;
    UINT64 GPUBusyDuration;
} D3D12XBOX_RENDER_STATISTICS;
```

`GPUBusyDuration` 是**归一化的** —— 它假设 GPU 时钟处于 P4,且与当前电源状态无关。power-scaling 帧统计**会**受到电源状态变化的影响,并且会与 `GPUBusyDuration` 不同。

### 示例

一段在 P4 下需要 8 ms 的 GPU 工作,在 P2 下(时钟更低)会延长到 12 ms:

| 值                       | DPS 关闭(P4) | DPS 开启(P2) |
| ----------------------- | ---------- | ---------- |
| `GPUBusyDuration`       | 8 ms       | 8 ms       |
| `GPUBusyDurationScaled` | 8 ms       | 12 ms      |
| `ScaleFactor`           | 1          | 0.67       |

<Note>
  之所以保留归一化的 `GPUBusyDuration`,是因为游戏引擎会用它做动态分辨率计算。将**归一化**和**缩放**测量值分开,可避免反馈环路 —— 否则较低的电源状态会导致动态分辨率不断下降,直到降到最低。
</Note>

## 下一步

* [如何使用 PIX 进行可持续性分析](/build/game-principles/sustainability/sustainability-pix-guide)
* [可持续性开发者概览](/build/game-principles/sustainability/sustainability-developer-overview)
* [可持续性开发主机指南](/build/game-principles/sustainability/sustainability-devkit-guide)
* [能效基础要点](/build/game-principles/sustainability/energy-efficiency-essentials)


## Related topics

- [XBOX 游戏能效基础要点](/zh-CN/build/game-principles/sustainability/energy-efficiency-essentials.md)
- [可持续性概览](/zh-CN/build/game-principles/sustainability/sustainability-overview.md)
- [使用 PIX 进行可持续性分析](/zh-CN/build/game-principles/sustainability/sustainability-pix-guide.md)
- [可持续性案例研究概览](/zh-CN/build/game-principles/sustainability/case-studies/case-studies-overview.md)
- [可持续性开发者概览](/zh-CN/build/game-principles/sustainability/sustainability-developer-overview.md)
