ID3D11DeviceContext1::P SSetConstantBuffers1 方法 (d3d11_1.h)
设置像素着色器管道阶段使用的常量缓冲区,并使着色器能够访问缓冲区的其他部分。
语法
void PSSetConstantBuffers1(
[in] UINT StartSlot,
[in] UINT NumBuffers,
[in, optional] ID3D11Buffer * const *ppConstantBuffers,
[in, optional] const UINT *pFirstConstant,
[in, optional] const UINT *pNumConstants
);
参数
[in] StartSlot
类型: UINT
索引到设备的从零开始的数组中,开始将常量缓冲区设置为 (范围,范围为 0 到 D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - 1) 。
[in] NumBuffers
类型: UINT
要设置 (范围为 0 到 D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT 的缓冲区数 - StartSlot) 。
[in, optional] ppConstantBuffers
类型: ID3D11Buffer*
提供给设备的常量缓冲区数组。
[in, optional] pFirstConstant
类型: const UINT*
一个数组,该数组将偏移量放入 ppConstantBuffers 指定的缓冲区中。 每个偏移量指定从着色器的角度来看,每个常量缓冲区的开始位置。 每个偏移量以着色器常量度量,这些常量是 16 个字节 (4*32 位组件) 。 因此,偏移量为 16 表示关联常量缓冲区的开头为常量缓冲区中的 256 个字节。 每个偏移量必须是 16 个常量的倍数。
[in, optional] pNumConstants
类型: const UINT*
一个数组,该数组保存 ppConstantBuffers 指定的缓冲区中的常量数。 每个数字指定着色器使用的常量缓冲区中包含的常量数。 每个常量数从 pFirstConstant 数组中指定的相应偏移量开始。 每个常量数必须是 16 个常量的倍数,范围 [0..4096]。
返回值
无
备注
若要使着色器能够访问缓冲区的其他部分,请调用 PSSetConstantBuffers1 而不是 PSSetConstantBuffers。 PSSetConstantBuffers1 具有其他参数 pFirstConstant 和 pNumConstants。
如果 pNumConstants 指向的常量数大于着色器支持的最大常量缓冲区大小,则运行时将删除对 PSSetConstantBuffers1 的调用。 着色器支持的最大常量缓冲区大小包含 4096 个常量,其中每个常量有四个 32 位分量。
pFirstConstant 和 pFirstConstantpNumConstants + 数组的元素中的值可能超过每个缓冲区的长度;从着色器的角度来看,常量缓冲区是缓冲区的实际内存分配的交集,下面的窗口 (范围) :
[ pFirstConstant 元素中的 value, pFirstConstant 元素中的 value + pNumConstants 元素中的 value]
也就是说,窗口范围从 pFirstConstant) 元素中的 (值到 pNumConstants) 元素中的 pFirstConstant + value 元素中的 (值。
运行时还会在不支持此偏移的现有驱动程序上删除对 PSSetConstantBuffers1 的调用。
运行时将为 功能级别 9.1、9.2 和 9.3 模拟此功能;因此,功能级别 9.1、9.2 和 9.3 支持此功能。 此功能始终在功能级别 10 及更高级别的新驱动程序上可用。
从着色器的角度来看,常量缓冲区数组中的元素 [0] 是 pFirstConstant 处的常量。
对从着色器到 pFirstConstant 和 pNumConstants 定义的范围的常量缓冲区的边界外访问返回 0。
如果 pFirstConstant 和 pNumConstants 数组为 NULL,则得到的结果与将整个缓冲区绑定到视图中时的结果相同。 如果调用 PSSetConstantBuffers 方法,将得到相同的结果。 如果缓冲区大于着色器 (4096 个元素) 支持的最大常量缓冲区大小,则着色器只能访问前 4096 个常量。
如果 pFirstConstant 或 pNumConstants 为 NULL,则另一个参数也必须为 NULL。
使用命令列表仿真调用 PSSetConstantBuffers1
运行时的 命令列表 模拟 PSSetConstantBuffers1 有时实际上不会更改常量缓冲区数组的偏移量或大小。 当 PSSetConstantBuffers1 无法有效地更改您设置为更新的槽范围的开头和结尾处的常量缓冲区时,将发生此行为。 本部分介绍如何解决此行为。下面是用于检查运行时是模拟命令列表还是驱动程序支持命令列表的代码:
HRESULT hr = S_OK;
bool needWorkaround = false;
D3D11_DEVICE_CONTEXT_TYPE contextType = pDeviceContext->GetType();
if( D3D11_DEVICE_CONTEXT_DEFERRED == contextType)
{
D3D11_FEATURE_DATA_THREADING threadingCaps = { FALSE, FALSE };
hr = pDevice->CheckFeatureSupport( D3D11_FEATURE_THREADING, &threadingCaps, sizeof(threadingCaps) );
if( SUCCEEDED(hr) && !threadingCaps.DriverCommandLists )
{
needWorkaround = true; // the runtime emulates command lists.
}
}
如果运行时模拟命令列表,则需要使用以下代码片段之一:
如果仅更改单个常量缓冲区的偏移量和大小,请先将常量缓冲区设置为 NULL :
pDeviceContext->PSSetConstantBuffers1(0, 1, &CBuf, &Offset, &Count);
if( needWorkaround )
{
// Workaround for command list emulation
pDeviceContext->PSSetConstantBuffers(0, 1, &NullCBuf);
}
pDeviceContext->PSSetConstantBuffers1(0, 1, &CBuf, &Offset, &Count);
如果更改多个常量缓冲区,请先将范围的第一个和最后一个常量缓冲区设置为 NULL :
pDeviceContext->PSSetConstantBuffers1(0, 4, &CBufs, &Offsets, &Counts);
if( needWorkaround )
{
// Workaround for command list emulation
pDeviceContext->PSSetConstantBuffers(0, 1, &NullCBuf);
pDeviceContext->PSSetConstantBuffers(3, 1, &NullCBuf);
}
pDeviceContext->PSSetConstantBuffers1(0, 4, &CBufs, &Offsets, &Counts);
要求
最低受支持的客户端 | 适用于 Windows 7 的 Windows 8 和平台更新 [桌面应用 |UWP 应用] |
最低受支持的服务器 | Windows Server 2012 和适用于 Windows Server 2008 R2 的平台更新 [桌面应用 |UWP 应用] |
目标平台 | Windows |
标头 | d3d11_1.h |
Library | D3D11.lib |