window 显示驱动开发-创建压缩缓冲区和解码渲染器目标(一)

Microsoft Direct3D 运行时调用用户模式显示驱动程序的 CreateResource 函数,以创建压缩缓冲区和呈现目标以供解码。

每种压缩缓冲区类型都有自己的图面格式以及一个特殊标志,指示运行时创建的图面包含用于加速视频解码的压缩缓冲区信息。 如果设置了 CreateResource 的 pResource 参数指向的 D3DDDIARG_CREATERESOURCE 结构的 Flags 成员中的 DecodeCompressedBuffer 位字段标志,则用户模式显示驱动程序将决定创建压缩缓冲区。 用户模式显示驱动程序确定由 D3DDDIARG_CREATERESOURCE 的 Format 成员中的格式值创建的压缩缓冲区的类型。 定义了以下格式:

D3DDDIFMT_PICTUREPARAMSDATA       = 150
D3DDDIFMT_MACROBLOCKDATA          = 151
D3DDDIFMT_RESIDUALDIFFERENCEDATA  = 152
D3DDDIFMT_DEBLOCKINGDATA          = 153
D3DDDIFMT_INVERSEQUANTIZATIONDATA = 154
D3DDDIFMT_SLICECONTROLDATA        = 155
D3DDDIFMT_BITSTREAMDATA           = 156

Direct3D 运行时在调用用户模式显示驱动程序的 CreateResource 函数时独立创建每个解码呈现器目标。 每个目标都作为单个资源的子资源索引引用。 如果设置了 D3DDDIARG_CREATERESOURCE 的 Flags 成员中的 DecodeRenderTarget 位字段标志,则用户模式显示驱动程序将确定创建解码呈现目标。

资源创建架构概述

Microsoft Direct3D 运行时通过用户模式显示驱动程序的 CreateResource 函数创建两类关键解码资源:

  1. 压缩缓冲区:存储各种类型的压缩视频数据
  2. 渲染目标:接收解码后的视频帧输出

压缩缓冲区创建规范

标识与创建机制
当需要创建压缩缓冲区时,运行时会在 D3DDDIARG_CREATERESOURCE 结构中设置特定标志:

typedef struct _D3DDDIARG_CREATERESOURCE {
    D3DDDIFORMAT Format;          // 缓冲区格式标识
    UINT Flags;                   // 包含DecodeCompressedBuffer标志
    // ...其他字段
} D3DDDIARG_CREATERESOURCE;

关键标志位:

#define D3DDDI_DECODECOMPRESSEDBUFFER 0x00040000

专用压缩缓冲区格式

格式值 常量定义 对应缓冲区类型
150 D3DDDIFMT_PICTUREPARAMSDATA 图像参数数据
151 D3DDDIFMT_MACROBLOCKDATA 宏块控制数据
152 D3DDDIFMT_RESIDUALDIFFERENCEDATA 残差差异数据
153 D3DDDIFMT_DEBLOCKINGDATA 去块滤波数据
154 D3DDDIFMT_INVERSEQUANTIZATIONDATA 反量化矩阵数据
155 D3DDDIFMT_SLICECONTROLDATA 片控制数据
156 D3DDDIFMT_BITSTREAMDATA 视频位流数据

驱动程序实现要点

格式验证:

BOOL IsCompressedBufferFormat(D3DDDIFORMAT format) {
    return (format >= 150 && format <= 156);
}

资源特性配置:

  1. 设置正确的内存池(通常为D3DDDIPOOL_VIDEOMEMORY)
  2. 配置适当的内存对齐(通常16或128字节)
  3. 根据之前查询的缓冲区信息设置大小

硬件资源分配:

HRESULT CreateCompressedBuffer(
    const D3DDDIARG_CREATERESOURCE* pCreateData)
{
    BufferType type = MapFormatToBufferType(pCreateData->Format);
    return AllocateHWBuffer(type, pCreateData->pSurfList[0].Width);
}

渲染目标创建规范

标识与创建机制

渲染目标通过以下标志标识:

#define D3DDDI_DECODERENDERTARGET 0x00080000

关键特征

多子资源管理:

  • 每个渲染目标作为单个资源的子资源
  • 通过子资源索引引用

格式要求:

  • 必须匹配之前查询的支持格式(如D3DDDIFMT_NV12)
  • 分辨率与视频流一致

驱动程序实现要点

表面配置:

D3DDDI_SURFACEINFO surfInfo = {
    pCreateData->pSurfList[0].Width,
    pCreateData->pSurfList[0].Height,
    pCreateData->pSurfList[0].Pitch
};

内存优化:

  • 使用平铺布局提升访问效率
  • 考虑UMA架构的特殊处理

硬件兼容性:

if (!CheckRTFormatSupport(pCreateData->Format)) {
    return E_INVALIDARG;
}

完整创建流程示例

运行时调用序列

  1. 查询解码能力(GUID、格式、缓冲区信息)
  2. 创建解码设备
  3. 创建所需压缩缓冲区:
// 创建位流缓冲区示例
D3DDDIARG_CREATERESOURCE createBitstream = {
    D3DDDIFMT_BITSTREAMDATA,
    D3DDDI_DECODECOMPRESSEDBUFFER,
    // ...其他参数
};
pDevice->CreateResource(&createBitstream);

创建渲染目标:

D3DDDIARG_CREATERESOURCE createRT = {
    D3DDDIFMT_NV12,
    D3DDDI_DECODERENDERTARGET,
    // ...其他参数
};
pDevice->CreateResource(&createRT);

驱动程序资源管理

压缩缓冲区结构:

struct CompressedBuffer {
    BufferType type;      // 缓冲区类型枚举
    void* hwMemory;       // 硬件内存指针
    UINT alignedSize;     // 对齐后的大小
    D3DDDIFORMAT format;  // 格式标识
};

渲染目标结构:

struct DecodeRenderTarget {
    D3DDDIFORMAT format;  // NV12/YUY2等
    UINT width, height;   // 分辨率
    UINT arrayIndex;      // 子资源索引
    SurfaceHandle handle; // 表面句柄
};

高级实现技术

内存优化策略
压缩缓冲区池

static std::map g_bufferPools;

表面重用:

  • 实现表面循环队列
  • 动态调整表面数量

错误恢复机制

设备丢失处理:

HRESULT RecreateResourcesAfterLoss() {
    // 重新创建所有压缩缓冲区和渲染目标
}

后备分配:

if (FAILED(AllocateVideoMemory())) {
    AllocateSystemMemoryFallback();
}

性能考量

异步创建:

  • 对大型资源使用后台创建线程
  • 实现资源准备状态机

零拷贝集成:

if (IsZeroCopySupported()) {
    SetSharedMemoryMapping();
}

此资源创建机制为视频解码提供了灵活高效的硬件资源管理方案,驱动程序实现时应确保:

  • 严格验证所有创建参数
  • 优化内存访问模式
  • 正确处理多线程场景
  • 提供完善的错误恢复路径

你可能感兴趣的:(windows图形显示驱动开发,驱动开发)