OBS-Direct11数据结构
+ -

Stage Surface暂存表面-特殊的纹理

2026-01-30 4 0

Stage Surface(暂存表面)是 DirectX 中的一种特殊类型的纹理资源,全称为”Staging Resource”,主要用于GPU 与 CPU 之间的数据传输

在 OBS Studio 中,gs_stage_surface 类封装了 DirectX 11 的暂存纹理功能,提供了 GPU 到 CPU 的数据传输能力。

核心特性

  1. CPU 可访问

    • 具有 D3D11_CPU_ACCESS_READ 标志,允许 CPU 读取数据
    • 使用 D3D11_USAGE_STAGING 用法,专门用于数据传输
  2. 数据传输桥梁

    • 作为 GPU 资源和 CPU 内存之间的中间缓冲区
    • 支持从 GPU 可写资源复制到 CPU 可读的暂存表面
  3. 格式支持

    • 支持多种颜色格式,如 RGBA、BGRA 等
    • 特别支持 NV12 格式,用于视频编码场景

在 DirectX 中的工作流程

  1. 创建暂存表面:配置为 D3D11_USAGE_STAGINGD3D11_CPU_ACCESS_READ
  2. 从 GPU 复制数据:使用 CopyResourceCopySubresourceRegion
  3. 映射到 CPU 内存:使用 Map 方法获取 CPU 可访问的指针
  4. 读取数据:CPU 读取映射内存中的数据
  5. 取消映射:使用 Unmap 方法释放映射

典型应用场景

  1. 视频编码

    • 将渲染结果从 GPU 复制到暂存表面
    • CPU 读取暂存表面数据并传递给编码器
    • 特别支持 NV12 格式,优化视频编码性能
  2. 屏幕截图

    • 捕获当前渲染目标内容
    • 复制到暂存表面并读取数据
    • 保存为图像文件或传输到其他系统
  3. 数据处理

    • CPU 访问 GPU 生成的数据
    • 进行 CPU 端的数据处理或分析
    • 将处理后的数据传回 GPU
  4. 调试和分析

    • 检查 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,可以在保证功能的同时,尽可能减少数据传输对性能的影响。

0 篇笔记 写笔记

Stage Surface暂存表面-特殊的纹理
Stage Surface(暂存表面)是 DirectX 中的一种特殊类型的纹理资源,全称为”Staging Resource”,主要用于GPU 与 CPU 之间的数据传输。在 OBS Studio 中,gs_stage_surface 类封装了 DirectX 11 的暂存纹理功能,提供了 GP......
作者信息
站长漫谈
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!