DirectCompute & DirectX 11 计算着色器编程简介(翻译)

时间:2009-12-13   来源:   网友评论:0   人气: 1459 作者:

译者注:DirectX一直是Windows上图形和游戏开发的核心技术。DirectX提供了一种在显卡上运行的程序——着色器(Shader)。在DirectX 11之前,着色器是与具体的渲染步骤绑定的,例如像素着色器,顶点着色器等等。而从DirectX11开始,DirectX增加了一种计算着色器(Compute Shader),它是专门为与图形无关的通用计算设计的。因此DirectX就变成了一个通用GPU计算的平台。鉴于GPU拥有极其强大的并行运算能力,学习使用DirectCompute是很有意义的。而大部分人从未用过DirectX的图形接口,缺乏使用DirectX的经验。本文是一篇完全从零开始学习DirectCompute通用计算技术的文章,无需图形编程经验,所以我就把它翻译过来了。有兴趣的兄弟可以看看学学。

原文地址:http://openvidia.sourceforge.net/index.php/DirectCompute

本文将介绍DirectCompute程序设计,旨在为没有DirectX编程经验的人展示DirectCompute从头开始进行程序设计的一些概念。本文还将介绍DirectX 11计算着色器(Compute Shader)。希望本文可以帮助大家了解使用DirectCompute进行GPU通用计算技术的相关知识。

示例代码介绍

完整示例代码 该链接包含了一个基于控制台的完整DirectCompute程序所需的最小代码示例(.cpp)。该程序是控制台程序,不含任何窗口或图形代码。

计算着色器代码 该链接包含了完整的着色器代码(.hlsl)

示例程序深入展示了以下几个运行计算着色器所需的以下步骤:

  1. 初始化设备和上下文
  2. 从HLSL文件加载着色器程序并编译
  3. 为着色器创建并初始化资源(如缓冲区)
  4. 设定着色器状态,并执行
  5. 取回运算结果。

下面将逐个讨论每一个步骤

设备管理

基本上,DirectCompute需要通过计算着色器5.0(Compute Shader)编程模型(即CS 5.0)才能完全实现。然而CS 5.0需要DirectX 11硬件才能支持。如果没有Direct X 11硬件(本文编写时Direct X 11硬件还非常稀少,仅有Ati HD5000系列显卡),我们仍然可以进行DirectCompute编程,一种方法是使用参考硬件模式(软件模拟),另一种方法是使用落后一点的配置,在DirectX 10硬件上运行可以实现部分计算着色器能力的“计算着色器4.0”(如nVidia G80, G92, GT200系列显卡)。做法是:

  • 使用DirectX 11 API编写程序(比如调用ID3D11…)
  • 创建DX11设备,但是创建时指定使用DX10和CS 4.0特性等级。

下面的代码演示如何多次调用D3D11CreateDevice…()方法,每次创建一种不同的驱动类型(软件模拟的参考型或真正GPU加速的硬件型),以及不同的特性等级(DX10、DX10.1或DX11)

D3D_FEATURE_LEVEL levelsWanted[] = 
{ 
    D3D_FEATURE_LEVEL_11_0, 
    D3D_FEATURE_LEVEL_10_1, 
    D3D_FEATURE_LEVEL_10_0
};
UINT numLevelsWanted = sizeof( levelsWanted ) / sizeof( levelsWanted[0] );
 
D3D_DRIVER_TYPE driverTypes[] =
{
    D3D_DRIVER_TYPE_REFERENCE,
    D3D_DRIVER_TYPE_HARDWARE,
};
UINT numDriverTypes = sizeof( driverTypes ) / sizeof( driverTypes[0] );

// 遍历每一种驱动类型,先尝试参考驱动,然后是硬件驱动
// 成功创建一种之后就退出循环。
// 你可以更改以上顺序来尝试各种配置
// 这里我们只需要参考设备来演示API调用
for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
{
    D3D_DRIVER_TYPE g_driverType = driverTypes[driverTypeIndex];
    UINT createDeviceFlags = NULL;
    hr = D3D11CreateDevice( NULL, g_driverType, NULL, createDeviceFlags, 
        levelsWanted, numLevelsWanted, D3D11_SDK_VERSION, 
        &g_pD3DDevice, &g_D3DFeatureLevel, &g_pD3DContext );
}


 

文章评论