Stage Surface暂存表面-特殊的纹理
2026-01-30
4
0
Stage Surface(暂存表面)是 DirectX 中的一种特殊类型的纹理资源,全称为”Staging Resource”,主要用于GPU 与 CPU 之间的数据传输。
在 OBS Studio 中,gs_stage_surface 类封装了 DirectX 11 的暂存纹理功能,提供了 GPU 到 CPU 的数据传输能力。
核心特性
CPU 可访问:
- 具有
D3D11_CPU_ACCESS_READ标志,允许 CPU 读取数据 - 使用
D3D11_USAGE_STAGING用法,专门用于数据传输
- 具有
数据传输桥梁:
- 作为 GPU 资源和 CPU 内存之间的中间缓冲区
- 支持从 GPU 可写资源复制到 CPU 可读的暂存表面
格式支持:
- 支持多种颜色格式,如 RGBA、BGRA 等
- 特别支持 NV12 格式,用于视频编码场景
在 DirectX 中的工作流程
- 创建暂存表面:配置为
D3D11_USAGE_STAGING和D3D11_CPU_ACCESS_READ - 从 GPU 复制数据:使用
CopyResource或CopySubresourceRegion - 映射到 CPU 内存:使用
Map方法获取 CPU 可访问的指针 - 读取数据:CPU 读取映射内存中的数据
- 取消映射:使用
Unmap方法释放映射
典型应用场景
视频编码:
- 将渲染结果从 GPU 复制到暂存表面
- CPU 读取暂存表面数据并传递给编码器
- 特别支持 NV12 格式,优化视频编码性能
屏幕截图:
- 捕获当前渲染目标内容
- 复制到暂存表面并读取数据
- 保存为图像文件或传输到其他系统
数据处理:
- CPU 访问 GPU 生成的数据
- 进行 CPU 端的数据处理或分析
- 将处理后的数据传回 GPU
调试和分析:
- 检查 GPU 纹理的实际内容
- 分析渲染结果的正确性
- 性能分析和优化
与普通纹理的区别
| 特性 | Stage Surface | 普通纹理 |
|---|---|---|
| CPU 访问 | 可读 | 通常不可直接访问 |
| GPU 访问 | 不可作为渲染目标或着色器资源 | 可作为渲染目标或着色器资源 |
| 用途 | 数据传输 | 渲染和着色器操作 |
| 性能 | 数据传输开销较大 | 渲染性能优化 |
| 格式 | 支持多种格式,包括 NV12 | 支持渲染相关格式 |
在 OBS 中的应用
gs_stagesurf_t *copy = video->copy_surfaces[cur_texture][0];
//将output_texture纹理数据复制到copy中
gs_stage_texture(copy, video->output_texture);
函数如下:
void device_stage_texture(gs_device_t *device, gs_stagesurf_t *dst,
gs_texture_t *src)
{
gs_texture_2d *src2d = static_cast<gs_texture_2d *>(src);
device->CopyTex(dst->texture, 0, 0, src, 0, 0, 0, 0);
}
inline void gs_device::CopyTex(ID3D11Texture2D *dst, uint32_t dst_x,
uint32_t dst_y, gs_texture_t *src,
uint32_t src_x, uint32_t src_y, uint32_t src_w,
uint32_t src_h)
{
if (src->type != GS_TEXTURE_2D)
throw "Source texture must be a 2D texture";
gs_texture_2d *tex2d = static_cast<gs_texture_2d *>(src);
if (dst_x == 0 && dst_y == 0 && src_x == 0 && src_y == 0 && src_w == 0 && src_h == 0)
{
context->CopyResource(dst, tex2d->texture);
}
else
{
D3D11_BOX sbox;
sbox.left = src_x;
if (src_w > 0)
sbox.right = src_x + src_w;
else
sbox.right = tex2d->width - 1;
sbox.top = src_y;
if (src_h > 0)
sbox.bottom = src_y + src_h;
else
sbox.bottom = tex2d->height - 1;
sbox.front = 0;
sbox.back = 1;
context->CopySubresourceRegion(dst, 0, dst_x, dst_y, 0,tex2d->texture, 0, &sbox);
}
}
暂存表面在OBS中创建也是分为2种,一种是普通的,另一种是NV12格式的。
性能考量
- 数据传输开销:从 GPU 到 CPU 的数据传输是相对昂贵的操作
- 异步传输:在可能的情况下,应使用异步传输以减少性能影响
- 格式选择:选择合适的格式(如 NV12)可以减少传输的数据量
- 大小优化:只传输必要的数据,避免不必要的大范围复制
总结
Stage Surface 是 OBS Studio 中实现 GPU 到 CPU 数据传输的关键组件,特别适用于需要 CPU 访问 GPU 渲染结果的场景,如屏幕截图、视频编码和数据处理。通过合理使用 Stage Surface,可以在保证功能的同时,尽可能减少数据传输对性能的影响。
OBS-Direct11数据结构





