I want to use StructuredBuffer<float>
variable in vertex shader (this is just an example):
struct VS_INPUT
{
float4 pos : POSITION;
float4 color : COLOR;
uint id : SV_VERTEXID;
};
struct VS_OUTPUT
{
float4 pos : SV_POSITION;
float4 color : COLOR;
};
cbuffer Constant_Buffer : register(b0)
{
float4x4 wvpMat;
};
StructuredBuffer<float> data : register(t0);
VS_OUTPUT main(VS_INPUT input)
{
VS_OUTPUT output;
output.pos = mul(input.pos, wvpMat);
output.color = input.color;
float4 color = input.color;
if (data[0] != 0.0f)
{
color.x = 1.0f;
}
output.color = color;
return output;
}
But my app crashes. It works fine when I remove any expression containing the data
variable.
How I created this buffer on CPU side:
D3D12_DESCRIPTOR_HEAP_DESC srvHeapDesc = {};
srvHeapDesc.NumDescriptors = 1;
srvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
srvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
device->CreateDescriptorHeap(&srvHeapDesc, IID_PPV_ARGS(&srvDescriptorHeap));
srvDescriptorSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
UINT dataSize = data_count * sizeof(float);
D3D12_HEAP_PROPERTIES defaultHeapProperties = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
D3D12_RESOURCE_DESC bufferDesc = CD3DX12_RESOURCE_DESC::Buffer(dataSize, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
D3D12_HEAP_PROPERTIES uploadHeapProperties = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_UPLOAD);
D3D12_RESOURCE_DESC uploadBufferDesc = CD3DX12_RESOURCE_DESC::Buffer(dataSize);
device->CreateCommittedResource(
&defaultHeapProperties,
D3D12_HEAP_FLAG_NONE,
&bufferDesc,
D3D12_RESOURCE_STATE_COPY_DEST,
nullptr,
IID_PPV_ARGS(&float_buffer));
device->CreateCommittedResource(
&uploadHeapProperties,
D3D12_HEAP_FLAG_NONE,
&uploadBufferDesc,
D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr,
IID_PPV_ARGS(&float_buffer_upload));
std::vector<float> data(data_count, 1.0f);
D3D12_SUBRESOURCE_DATA particleData = {};
particleData.pData = reinterpret_cast<UINT8*>(&data[0]);
particleData.RowPitch = dataSize;
particleData.SlicePitch = particleData.RowPitch;
UpdateSubresources<1>(commandList, float_buffer, float_buffer_upload, 0, 0, 1, &particleData);
commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(float_buffer, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE));
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
srvDesc.Format = DXGI_FORMAT_UNKNOWN;
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
srvDesc.Buffer.FirstElement = 0;
srvDesc.Buffer.NumElements = data_count;
srvDesc.Buffer.StructureByteStride = sizeof(float);
srvDesc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle(srvDescriptorHeap->GetCPUDescriptorHandleForHeapStart(), 0, srvDescriptorSize);
device->CreateShaderResourceView(float_buffer, &srvDesc, srvHandle);
As you can see, I did initialize the buffer. It’s filled with 1.0f.
The graphics root signature:
D3D12_ROOT_DESCRIPTOR rootCBVDescriptor;
rootCBVDescriptor.RegisterSpace = 0;
rootCBVDescriptor.ShaderRegister = 0;
D3D12_DESCRIPTOR_RANGE range = {};
range.BaseShaderRegister = 0;
range.NumDescriptors = 1;
range.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV;
range.OffsetInDescriptorsFromTableStart = 0;
CD3DX12_ROOT_PARAMETER rootParameters[2];
rootParameters[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV;
rootParameters[0].Descriptor = rootCBVDescriptor;
rootParameters[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX;
rootParameters[1].InitAsDescriptorTable(1, &range);
How I bind it to a command list:
commandList->SetGraphicsRootConstantBufferView(0, constantBufferUploadHeaps[frameIndex]->GetGPUVirtualAddress());
CD3DX12_GPU_DESCRIPTOR_HANDLE srvHandle(srvDescriptorHeap->GetGPUDescriptorHandleForHeapStart());
commandList->SetGraphicsRootDescriptorTable(1, srvHandle);
Please help, what am I missing?