D3DCompile2 函数 (d3dcompiler.h)
将 Microsoft 高级着色器语言 (HLSL) 代码编译为给定目标的字节码。
语法
HRESULT D3DCompile2(
[in] LPCVOID pSrcData,
[in] SIZE_T SrcDataSize,
[in, optional] LPCSTR pSourceName,
[in, optional] const D3D_SHADER_MACRO *pDefines,
[in, optional] ID3DInclude *pInclude,
[in] LPCSTR pEntrypoint,
[in] LPCSTR pTarget,
[in] UINT Flags1,
[in] UINT Flags2,
[in] UINT SecondaryDataFlags,
[in, optional] LPCVOID pSecondaryData,
[in] SIZE_T SecondaryDataSize,
[out] ID3DBlob **ppCode,
[out, optional] ID3DBlob **ppErrorMsgs
);
参数
[in] pSrcData
类型: LPCVOID
指向未编译着色器数据的指针, (ASCII HLSL 代码) 。
[in] SrcDataSize
类型: SIZE_T
pSrcData 指向的内存块的大小(以字节为单位)。
[in, optional] pSourceName
类型: LPCSTR
指向以 null 结尾的常量字符串的可选指针,该字符串包含标识在错误消息中使用的源数据的名称。 如果未使用,则设置为 NULL。
[in, optional] pDefines
类型: const D3D_SHADER_MACRO*
定义着色器宏的 可选D3D_SHADER_MACRO 结构数组。 每个宏定义都包含一个名称和一个以 null 结尾的定义。 如果未使用,则设置为 NULL。 数组中的最后一个结构充当终止符,并且必须将所有成员设置为 NULL。
[in, optional] pInclude
类型: ID3DInclude*
指向编译器用于处理包含文件的 ID3DInclude 接口的指针。 如果将此参数设置为 NULL ,并且着色器包含 #include,则会发生编译错误。 可以传递 D3D_COMPILE_STANDARD_FILE_INCLUDE 宏,该宏是指向默认包含处理程序的指针。 此默认包含处理程序包括相对于当前目录的文件和相对于初始源文件目录的文件。 使用 D3D_COMPILE_STANDARD_FILE_INCLUDE 时,必须在 pSourceName 参数中指定源文件名称;编译器将从 pSourceName 派生初始相对目录。
#define D3D_COMPILE_STANDARD_FILE_INCLUDE ((ID3DInclude*)(UINT_PTR)1)
[in] pEntrypoint
类型: LPCSTR
指向以 null 结尾的常量字符串的指针,该字符串包含着色器执行开始位置的着色器入口点函数的名称。 编译效果时, D3DCompile2 会忽略 pEntrypoint;建议将 pEntrypoint 设置为 NULL ,因为如果调用的函数不使用指针参数,则最好将指针参数设置为 NULL 。
[in] pTarget
类型: LPCSTR
指向以 null 结尾的常量字符串的指针,该字符串指定要编译的着色器目标或着色器功能集。 着色器目标可以是着色器模型 (例如着色器模型 2、着色器模型 3、着色器模型 4 或着色器模型 5) 。 目标也可以是效果类型 (,例如,fx_4_1) 。 有关各种配置文件支持的目标的信息,请参阅 指定编译器目标。
[in] Flags1
类型: UINT
使用按位 OR 运算组合的着色器 D3D 编译常量的组合。 生成的值指定编译器如何编译 HLSL 代码。
[in] Flags2
类型: UINT
通过使用按位 OR 运算组合的效果 D3D 编译效果常量的组合。 生成的值指定编译器如何编译效果。 编译着色器而不是效果文件时, D3DCompile2 将忽略 Flags2;建议将 Flags2 设置为零,因为如果调用的函数不使用非pointer 参数,则最好将非pointer 参数设置为零。
[in] SecondaryDataFlags
类型: UINT
使用按位 OR 运算组合的以下标志的组合。 生成的值指定编译器如何编译 HLSL 代码。
标志 | 描述 |
---|---|
D3DCOMPILE_SECDATA_MERGE_UAV_SLOTS (0x01) | 将无序访问视图 (UAV) pSecondaryData 参数指向的辅助数据中的槽合并。 |
D3DCOMPILE_SECDATA_PRESERVE_TEMPLATE_SLOTS (0x02) | 在 pSecondaryData 参数指向的辅助数据中保留模板槽。 |
D3DCOMPILE_SECDATA_REQUIRE_TEMPLATE_MATCH (0x04) | 在编译器编译 HLSL 代码时,要求 pSecondaryData 参数指向的辅助数据中的模板匹配。 |
如果 pSecondaryData 为 NULL,请将 设置为零。
[in, optional] pSecondaryData
类型: LPCVOID
指向辅助数据的指针。 如果未传递辅助数据,请将 设置为 NULL。 使用此辅助数据在两个着色器中对齐 UAV 槽。 假设着色器 A 具有 UAV,并且它们绑定到某些槽。 若要编译着色器 B,以便将具有相同名称的 UAV 在 B 中映射到与 A 中相同的槽,请将 A 的字节代码作为辅助数据传递给 D3DCompile2 。
[in] SecondaryDataSize
类型: SIZE_T
pSecondaryData 指向的内存块的大小(以字节为单位)。 如果 pSecondaryData 为 NULL,请将 设置为零。
[out] ppCode
类型: ID3DBlob**
指向变量的指针,该变量接收指向可用于访问已编译代码的 ID3DBlob 接口的指针。
[out, optional] ppErrorMsgs
类型: ID3DBlob**
指向变量的指针,该变量接收指向可用于访问编译器错误消息的 ID3DBlob 接口的指针;如果没有错误,则为 NULL 。
返回值
类型: HRESULT
注解
D3DCompile2 和 D3DCompile 的区别在于,D3DCompile2 采用一些可选参数 (SecondaryDataFlags、pSecondaryData 和 SecondaryDataSize) ,可用于控制字节码生成方式的某些方面。 有关更多详细信息,请参阅这些参数的说明。 否则,D3DCompile2 和 D3DCompile 之间生成的字节码效率没有差异。
编译 UWP 的着色器
若要编译脱机着色器,建议使用 效果编译器工具。 如果无法提前编译所有着色器,请考虑编译更昂贵的着色器以及启动和最区分性能的路径所需的着色器,并在运行时编译其余的着色器。 可以使用类似于下面的进程在 UWP 应用程序中编译已加载或生成的着色器,而不会阻止用户界面线程。
使用 Visual Studio 2015+ 开发 UWP 应用,添加新项“shader.hlsl”。
- 在 Visual Studio 的 “解决方案文件夹” 视图中,选择 shaders.hlsl 项,右键单击“ 属性”。
- 确保项目 “内容 ”设置为“ 是”。
- 确保“ 项类型” 设置为 “文本”。
- 将按钮添加到 XAML,在此示例中 (“TheButton”) 适当地将其命名,并添加 Click 处理程序。
现在,将这些包含项添加到.cpp文件:
#include <ppltasks.h> #include <d3dcompiler.h> #include <Robuffer.h>
使用以下代码调用 D3DCompile2。 请注意,此处没有错误检查或处理,并且此代码还演示了你可以在后台执行 I/O 和编译,这会使 UI 更具响应性。
void App1::DirectXPage::TheButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
std::shared_ptr<Microsoft::WRL::ComPtr<ID3DBlob>> blobRef = std::make_shared<Microsoft::WRL::ComPtr<ID3DBlob>>();
// Load a file and compile it.
auto fileOp = Windows::ApplicationModel::Package::Current->InstalledLocation->GetFileAsync(L"shader.hlsl");
create_task(fileOp).then([this](Windows::Storage::StorageFile^ file) -> IAsyncOperation<Windows::Storage::Streams::IBuffer^>^
{
// Do file I/O in background thread (use_arbitrary).
return Windows::Storage::FileIO::ReadBufferAsync(file);
}, task_continuation_context::use_arbitrary())
.then([this, blobRef](Windows::Storage::Streams::IBuffer^ buffer)
{
// Do compilation in background thread (use_arbitrary).
// Cast to Object^, then to its underlying IInspectable interface.
Microsoft::WRL::ComPtr<IInspectable> insp(reinterpret_cast<IInspectable*>(buffer));
// Query the IBufferByteAccess interface.
Microsoft::WRL::ComPtr<Windows::Storage::Streams::IBufferByteAccess> bufferByteAccess;
insp.As(&bufferByteAccess);
// Retrieve the buffer data.
byte *pBytes = nullptr;
bufferByteAccess->Buffer(&pBytes);
Microsoft::WRL::ComPtr<ID3DBlob> blob;
Microsoft::WRL::ComPtr<ID3DBlob> errMsgs;
D3DCompile2(pBytes, buffer->Length, "shader.hlsl", nullptr, nullptr, "main", "ps_5_0", 0, 0, 0, nullptr, 0, blob.GetAddressOf(), errMsgs.GetAddressOf());
*blobRef = blob;
}, task_continuation_context::use_arbitrary())
.then([this, blobRef]()
{
// Update UI / use shader on foreground thread.
wchar_t message[40];
swprintf_s(message, L"blob is %u bytes long", (unsigned)(*blobRef)->GetBufferSize());
this->TheButton->Content = ref new Platform::String(message);
}, task_continuation_context::use_current());
}
要求
要求 | 值 |
---|---|
目标平台 | Windows |
标头 | d3dcompiler.h |
Library | D3DCompiler.lib |
DLL | D3DCompiler_47.dll |