C++ RWStructuredBuffer计数器不递减(DX12)
我正在尝试使用DX12在DXR中实现光子映射。撇开细节不谈,我有一个存储光子的结构化缓冲区。缓冲区从最近的命中着色器中写入,我通过计数器从多个线程组同步写入该缓冲区。这是可行的,我的光子被愉快地存储了起来。然后,我为这个缓冲区内的所有光子调用一个实例绘制,这将光栅化它们在屏幕上的飞溅半径。理论上,我应该能够减少这个绘制的顶点着色器中的计数器,并使其返回到0。但是,即使我这样做,计数器也不会重置为0。这意味着,当我每帧移动光源时,光子缓冲区不会更新,因为它从初始帧开始已经满了。任何关于我做错了什么的帮助都会很好。:) 注意-我曾尝试在hlsl中使用InterlockedAdd(countingBufferIndex,1,dstIndex)来同步对缓冲区的访问,而不是调用dstIndex=buffer.IncrementCounter(),但是在这种情况下,只有少量光子被推送到缓冲区-查看Pix或NSight中的内存,只有大约百分之一的缓冲区被填满C++ RWStructuredBuffer计数器不递减(DX12),c++,directx,hlsl,raytracing,directx-12,C++,Directx,Hlsl,Raytracing,Directx 12,我正在尝试使用DX12在DXR中实现光子映射。撇开细节不谈,我有一个存储光子的结构化缓冲区。缓冲区从最近的命中着色器中写入,我通过计数器从多个线程组同步写入该缓冲区。这是可行的,我的光子被愉快地存储了起来。然后,我为这个缓冲区内的所有光子调用一个实例绘制,这将光栅化它们在屏幕上的飞溅半径。理论上,我应该能够减少这个绘制的顶点着色器中的计数器,并使其返回到0。但是,即使我这样做,计数器也不会重置为0。这意味着,当我每帧移动光源时,光子缓冲区不会更新,因为它从初始帧开始已经满了。任何关于我做错了什么
//create the counting buffer for the photons
void Application::CreateCountBuffer() {
auto device = m_deviceResources->GetD3DDevice();
UINT size = 4;
D3D12_RESOURCE_DESC desc = {};
desc.Alignment = 0;
desc.DepthOrArraySize = 1;
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
desc.Format = DXGI_FORMAT_UNKNOWN;
desc.Height = 1;
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
desc.MipLevels = 1;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Width = (UINT64)size;
auto heapProps = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
ThrowIfFailed(device->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, nullptr, IID_PPV_ARGS(&photonCountBuffer)));
photonCountBuffer->SetName(L"CountingPhotonsBuffer");
photonCounterDescriptorHeapIndex = AllocateDescriptor(&photonCountCPUDescriptor, photonCounterDescriptorHeapIndex);
D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
uavDesc.Format = DXGI_FORMAT_R32_TYPELESS;
uavDesc.Buffer.NumElements = 1;
uavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW;
device->CreateUnorderedAccessView(photonCountBuffer.Get(), nullptr, &uavDesc, photonCountCPUDescriptor);
photonCounterGpuDescriptor = CD3DX12_GPU_DESCRIPTOR_HANDLE(m_descriptorHeap->GetGPUDescriptorHandleForHeapStart(), photonCountUavDescriptorHeapIndex, m_descriptorSize);
}
///////////光线跟踪着色器中光子结构化缓冲区和计数器缓冲区的寄存器/////////////
RWStructuredBuffer photonBuffer:寄存器(u1);
rwByteAddressBufferPhotonBufferCounter:寄存器(u2);
////////////存储光子-在最近的命中着色器中调用/////////////////
uint dstIndex=photonBuffer.IncrementCounter();
float raySize=sqrt(点(pos-WorldRayOrigin(),pos-WorldRayOrigin());
光子p={float4(pos,raySize),float4(dir,1),float4(color,1),float4(attr.normal,1)};
如果(dstIndex<光子计数){
photonBuffer[dstIndex]=p;
}
否则{
uint decre=photonBuffer.DecrementCounter();
}
}
/////////////光栅管道中光子缓冲区的寄存器//////////////////////////////////////////////////////////////////////
RWStructuredBuffer光子:寄存器(u1);
//////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
///////////减量计数器-在实例化绘制的顶点着色器内调用(称为每光子)//////
/////////////////////////////////////////////////////////////////////////////////////////////////////
PSInput VSMain(浮点4位置:位置,uint实例ID:SV_实例ID,浮点4颜色:颜色)
{
浮动lMax=50;
浮点数MaxMajorkernerRadius=10;
float minMajKernelRadius=0.1;
浮点数pi=3.141592653589793238462642283279502841971F;
输入结果;
光子=光子[实例ID];
uint decre=光子。DecrementCounter();
.
.
.
}
//create the RWStructuredBuffer for storing the photons
void Application::CreatePhotonStructuredBuffer() {
auto device = m_deviceResources->GetD3DDevice();
auto backBufferFormat = m_deviceResources->GetBackBufferFormat();
{
UINT64 size = sizeof(Photon);
UINT64 bufferSize = PHOTON_COUNT * size;
auto uavDesc = CD3DX12_RESOURCE_DESC::Buffer(bufferSize, D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS);
auto defaultHeapProperties = CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT);
ThrowIfFailed(device->CreateCommittedResource(&defaultHeapProperties, D3D12_HEAP_FLAG_NONE, &uavDesc, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, nullptr, IID_PPV_ARGS(&photonStructBuffer)));
NAME_D3D12_OBJECT(photonStructBuffer);
photonStructGpuHeapIndex = AllocateDescriptor(&photonStructCPUDescriptor, photonStructGpuHeapIndex);
D3D12_UNORDERED_ACCESS_VIEW_DESC uavPhotonDesc = {};
uavPhotonDesc.Buffer.NumElements = PHOTON_COUNT;
uavPhotonDesc.Buffer.FirstElement = 0;
uavPhotonDesc.Buffer.StructureByteStride = size;
uavPhotonDesc.Buffer.CounterOffsetInBytes = 0;
uavPhotonDesc.Format = DXGI_FORMAT_UNKNOWN;
uavPhotonDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
device->CreateUnorderedAccessView(photonStructBuffer.Get(),photonCountBuffer.Get(), &uavPhotonDesc, photonStructCPUDescriptor);
photonStructGPUDescriptor = CD3DX12_GPU_DESCRIPTOR_HANDLE(m_descriptorHeap->GetGPUDescriptorHandleForHeapStart(), photonStructGpuHeapIndex, m_descriptorSize);
}
}
///////////Registers for Photon Structured Buffer and counter buffer within Ray-Tracing shader/////////////
RWStructuredBuffer<Photon> photonBuffer : register(u1);
RWByteAddressBuffer photonBufferCounter : register(u2);
////////////Storing Photons - called within a Closest Hit shader/////////////////
uint dstIndex = photonBuffer.IncrementCounter();
float raySize = sqrt(dot(pos - WorldRayOrigin(), pos - WorldRayOrigin()));
Photon p = { float4(pos, raySize), float4(dir, 1), float4(colour, 1), float4(attr.normal, 1) };
if (dstIndex < PHOTON_COUNT) {
photonBuffer[dstIndex] = p;
}
else {
uint decr = photonBuffer.DecrementCounter();
}
}
/////////////Register for Photon Buffer within Raster Pipeline //////////////////////////////////////////////////////////////////////
RWStructuredBuffer<Photon> photons : register(u1);
//////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////
///////////Decrement Counter - called within the vertex shader of an instanced draw (called per photon)//////
/////////////////////////////////////////////////////////////////////////////////////////////////////
PSInput VSMain(float4 position : POSITION, uint instanceID : SV_InstanceID, float4 color : COLOR)
{
float lMax = 50;
float maxMajorKernelRadius = 10;
float minMajKernelRadius = 0.1;
float pi = 3.1415926535897932384626422832795028841971f;
PSInput result;
Photon photon = photons[instanceID];
uint decr = photons.DecrementCounter();
.
.
.
}