Direct3D 12——计算着色器——结构化缓冲区资源

结构化缓冲区资源

以下示例展示了如何通过HLSL来定义结构化缓冲区

 struct Data
 {
      float3 v1;
      float3 v2;
};

StructuredBuffer<Data> gInputA : register(t0); 
StructuredBuffer<Data> glnputB : register(t1); 
RWStructuredBuffer<Data> gOutput : register(u0);

结构化缓冲区是一种由相同类型元素所构成的简单缓冲区——其本质上是一种数组。正如我们所看到的,该元素类型可以是用户以HLSL定义的结构体。

我们可以把为顶点缓冲区与索引缓冲区创建SRV的方法同样用于创建结构化缓冲区的SRV。除了“必 须指定D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS 标志“这一条之外,将结构化缓冲区用作UAV也与之前的操作基本一致。设置此标志的目的是用于把资源转换为D3D12_RESOURCE_ STATE_UNORDERED_ACCESS 状态。

struct Data
{
   XMFLOAT3 vl;
   XMFLOAT2 v2;
};

//生成一些数据来填充SRV缓冲区
std::vector<Data> dataA(NumDataElements); 
std::vector<Data> dataB(NumDataElements);

for(int i = 0; i < NumDataElements; ++i)
{
    dataA[i].v1=XMFLOAT3 (i,i,i);
    dataA[i].v2=XMFLOAT2 (i,0);
    
    dataB[i].v1=XMFLOAT3 (-i,i,0.0f);
    dataB[i].v2=XMFLOAT2 (0,-i);
}

UINT64 byteSize = dataA.size()*sizeof(Data);

//创建若干缓冲区用作SRV
mlnputBufferA = d3dUtil::CreateDefaultBuffer(
                            md3dDevice.Get(),
                            mCommandList.Get(),
                            dataA.data(),
                            byteSize,
                            mlnputUploadBufferA);

mlnputBufferB = d3dUtil::CreateDefaultBuffer(
                            md3dDevice.Get(),
                            mCommandList.Get(),
                            dataB.data(),
                            byteSize,
                            mlnputUploadBufferB);

//创建用作UAV的缓冲区
ThrowlfFailed(md3dDevice->CreateCommittedResource(
                          &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
                          D3DI2_HEAP_FLAG_NONE,
                          &CD3DX12_RESOURCE_DESC::Buffer(byteSize,
                                                  D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS),
                                                  D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
                                                  nullptr,
                                                  IID_PPV_ARGS(&mOutputBuffer)));

结构化缓冲区可以像纹理那样与流水线相绑定。我们为它们创建SRV或UAV的描述符,再将这些 描述符作为参数传入需要获取描述符表的根参数。或者,我们还能定义以根描述符为参数的根签名,由此便可以将资源的虚拟地址作为根参数直接进行传递,而无须涉及描述符堆(这种方式仅限于创建缓冲 区资源的SRV或UAV,并不适用于纹理)。考虑下列的根签名描述:

//根参数可以是描述符表、根描述符或根常量
CD3DX12_ROOT_PARAMETER slotRootParameter[3];

//性能优化小提示:按变更频率由高到低的顺序来填充根参数
slotRootParameter[0].InitAsShaderResourceView(0); 
slotRootParameter[1].InitAsShaderResourceView(1);
slotRootParameter[2].InitAsUnorderedAccessView(0);

//根签名由一系列根参数所构成
CD3DX12_ROOT_SIGNATURE_DESC rootSigDesc(3, slotRootParameter,0, nullptr,
D3D12_ROOT_SIGNATURE_FLAG_NONE);

接下来,我们就能绑定所创建的缓冲区以供分派调用使用:

mCommanciList->SetComputeRootSignature (mRootSignature . Get ());

mCommandList->SetComputeRootShaderReSourceView(0,mlnputBufferA->GetGPUVirtualAddress()); 

mCommandList->SetComputeRootShaderReSourceView(1, mlnputBufferB->GetGPUVirtualAddress());

mCommandList->SetComputeRootUnorderedAccessView(2,mOutputBuffer->GetGPUVirtualAddress());

mCommandList->Dispatch(1, 1, 1);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值