Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ RWStructuredBuffer计数器不递减(DX12)_C++_Directx_Hlsl_Raytracing_Directx 12 - Fatal编程技术网

C++ RWStructuredBuffer计数器不递减(DX12)

C++ RWStructuredBuffer计数器不递减(DX12),c++,directx,hlsl,raytracing,directx-12,C++,Directx,Hlsl,Raytracing,Directx 12,我正在尝试使用DX12在DXR中实现光子映射。撇开细节不谈,我有一个存储光子的结构化缓冲区。缓冲区从最近的命中着色器中写入,我通过计数器从多个线程组同步写入该缓冲区。这是可行的,我的光子被愉快地存储了起来。然后,我为这个缓冲区内的所有光子调用一个实例绘制,这将光栅化它们在屏幕上的飞溅半径。理论上,我应该能够减少这个绘制的顶点着色器中的计数器,并使其返回到0。但是,即使我这样做,计数器也不会重置为0。这意味着,当我每帧移动光源时,光子缓冲区不会更新,因为它从初始帧开始已经满了。任何关于我做错了什么

我正在尝试使用DX12在DXR中实现光子映射。撇开细节不谈,我有一个存储光子的结构化缓冲区。缓冲区从最近的命中着色器中写入,我通过计数器从多个线程组同步写入该缓冲区。这是可行的,我的光子被愉快地存储了起来。然后,我为这个缓冲区内的所有光子调用一个实例绘制,这将光栅化它们在屏幕上的飞溅半径。理论上,我应该能够减少这个绘制的顶点着色器中的计数器,并使其返回到0。但是,即使我这样做,计数器也不会重置为0。这意味着,当我每帧移动光源时,光子缓冲区不会更新,因为它从初始帧开始已经满了。任何关于我做错了什么的帮助都会很好。:)

注意-我曾尝试在hlsl中使用InterlockedAdd(countingBufferIndex,1,dstIndex)来同步对缓冲区的访问,而不是调用dstIndex=buffer.IncrementCounter(),但是在这种情况下,只有少量光子被推送到缓冲区-查看Pix或NSight中的内存,只有大约百分之一的缓冲区被填满

//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(&amp;defaultHeapProperties, D3D12_HEAP_FLAG_NONE, &amp;uavDesc, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, nullptr, IID_PPV_ARGS(&amp;photonStructBuffer)));
        NAME_D3D12_OBJECT(photonStructBuffer);

        photonStructGpuHeapIndex = AllocateDescriptor(&amp;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(), &amp;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();
    .
    .
    .
    }