HLSL
+ -

6.2 HLSL使用流程

2024-06-26 33 0

6.2.1编写HLSL和编译程序

使用过程从在HLSL中编写着色器程序开始。

通常,这是通过创建一个标准ASCII文本文件来完成的,该文件包含一个或多个着色器程序的代码。这可以通过任何标准文本编辑器或开发环境来完成。

一旦程序的代码编写完成,就会由D3D着色器编译器进行编译。通过D3D编译器DLL导出的D3D编译器函数或使用独立的fxc.exe工具通过命令行访问编译器。还有D3DX辅助函数(D3DXCompileFromFile\D3DXCompileFromResource),可以简化直接从文件或嵌入资源进行编译的过程。

通常情况下,编译器除了接受代码本身之外,还接受配置参数。这些参数指示入口函数、用于编译的着色器配置文件、预处理器宏定义列表、预处理器要包括的附加文件列表以及编译标志列表(包括优化和调试选项)。

如果编译失败或产生警告,D3DCompile和D3DX函数会将警告或错误消息存储在嵌入ID3D10Blob对象的字符串中。与C++编译一样,这些消息包括一条信息性消息和一个行号,因此可以很容易地找到并更正错误或警告。如果使用fxc.exe,消息将简单地输出到命令行。

对于应用程序的调试构建,通常需要在启用D3D10_shader_debug(fxc中的/Zi开关)标志的情况下编译着色器程序。这导致编译器将调试信息嵌入到字节码流中,字节码流可用于将指令和常量映射回HLSL源代码中相应的行。这允许对着色器程序进行源代码级调试,这比直接调试程序集要方便得多。请注意,也可能希望通过使用D3D10_SHADER_SKIP_optimizations(fxc中的/Od开关)来禁用优化,因为这将防止指令重新排序和折叠,从而更容易调试程序。

着色器程序可以使用PIX进行调试,PIX是DirectX SDK附带的一种调试和分析实用程序。

6.2.1字节码

一旦编译成功完成,编译器就会输出一种称为字节码的中间格式。这是一个不透明的二进制流,包含着色器的所有程序集指令,以及嵌入的反射和调试元数据。如果程序员想检查生成的汇编指令进行验证,可以通过使用D3D编译器DLL导出的D3DDisassemble函数来获得。命令行工具fxc.exe还将在编译完成时将程序集输出到命令行,或者可以将其配置为将程序集列表输出到文件。此外,PIX可用于检查D3D11着色器对象并查看程序集代码。有关着色器部件的详细信息,请参阅DirectX SDK文档中的HLSL参考部分。

6.2.3运行时着色器对象

一旦为着色器程序生成了字节码,就可以用于创建D3D11着色器对象。
ID3D11Device接口提供了六种创建着色器对象的方法,其中一种用于管道的每个可编程阶段。这些方法是CreateVertexShader、CreateHullShader、CreateDomainShader、reateGeometryShader、Create PixelShader和CreateComputeShader。其中每一个都接受一个字节码流,并生成一个ID3Dll*Shader接口,该接口表示可以绑定到管道的运行时着色器对象。
有关编译顶点着色器和创建运行时着色器对象的简单示例,请参见清单6.1。

    ID3D10Blob* compiledShader;
    ID3D10Blob* errorMessages;
    //编译顶点着色器程序源文件
    HRESULT hr = D3DXllCompileFromFile(filePath, NULL, NULL, "VSMain","vs_5_0", 0, 0, NULL, &compiledShader,&errorMessages, NULL );
    if ( FAILED( hr ) )
    {
        if ( errorMessages )
        {
            const char* msg = (char*)( errorMessages->GetBufferPointer() );
            Log::6et().Write( msg );
        }
        else
        {
            Log::Get().Write( "D3DXllCompileFromFile failed" );
        }
    }
    else
    {
        ID3DllVertexShader* vertexShader = NULL;
        //创建顶点着色器
        device->CreateVertexShader(compiledShader->GetBufferPointer(),
        compiledShader->GetBufferSize(),
        NULL,
        &vertexShader );
    }

6.2.4绑定到管道

色器对象通过调用ID3D11DeviceContext上可用的各种SetShader方法绑定到管道。一旦所有必需的着色器对象都绑定到其相应的阶段,就可以发出Draw调用,并且绑定的着色器程序将用于渲染几何体。或者,在计算着色器的情况下,可以发出Dispatch调用来使用计算管道。

绑定顶点着色器到管道

m_DeviceContext->VSSetShader(m_VertexShader, nullptr, 0);

如果着色器程序使用着色器资源、采样器或常量缓冲区,则在发出Draw或Dispatch调用之前必须绑定这些资源。这是通过在设备上下文上调用适当的SetShaderResource、SetConstantBuffers和SetSamplers方法来完成的。

未排序的访问视图使用CSSetUnorderedAccessViews绑定到计算着色器阶段,并使用OMSetRenderTargetsAndUnorderedAccess views绑定至像素着色器阶段。

0 篇笔记 写笔记

作者信息
站长漫谈
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

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

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