Particles/Compute.cpp
//-----------------------------------------------------------------------------
// Create two buffers in the GPU, each with a copy of the particles data
// The compute shader reads from one and writes to the other
//-----------------------------------------------------------------------------
Create two buffers in the GPU, each with a copy of the particles data
The compute shader reads from one and writes to the other
Create two buffers in the GPU each with a copy of the particles data The compute shader reads from one and writes to the other
void Compute::CreateSharedBuffers()
{
    const UINT dataSize = m_numParticles * sizeof(Render::Particle);
    const D3D12_RESOURCE_DESC crossAdapterDesc = CD3DX12_RESOURCE_DESC::Buffer(dataSize,
        D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS |
        D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER);
    const D3D12_RESOURCE_ALLOCATION_INFO textureInfo =
        m_device->GetResourceAllocationInfo(0, 1, &crossAdapterDesc);
    const UINT64 alignedDataSize = textureInfo.SizeInBytes;
    const CD3DX12_HEAP_DESC heapDesc(
        m_NUM_BUFFERS * alignedDataSize,
        D3D12_HEAP_TYPE_DEFAULT,
        0, 
        D3D12_HEAP_FLAG_SHARED | D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER);
    ThrowIfFailed(m_device->CreateHeap(&heapDesc, IID_PPV_ARGS(&m_sharedHeap)));
    ThrowIfFailed(m_device->CreateSharedHandle(m_sharedHeap.Get(), nullptr,
        GENERIC_ALL, 0, &m_sharedHandles.m_heap));
    m_sharedHandles.m_alignedDataSize = alignedDataSize;
    D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
    uavDesc.Format = DXGI_FORMAT_UNKNOWN;
    uavDesc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
    uavDesc.Buffer.FirstElement = 0;
    uavDesc.Buffer.NumElements = m_numParticles;
    uavDesc.Buffer.StructureByteStride = sizeof(Render::Particle);
    uavDesc.Buffer.CounterOffsetInBytes = 0;
    uavDesc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_NONE;
    D3D12_UNORDERED_ACCESS_VIEW_DESC velocityDesc = uavDesc;
    velocityDesc.Buffer.StructureByteStride = sizeof(ParticleVelocity);
    for (UINT i = 0; i < m_NUM_BUFFERS; i++)
    {
        ThrowIfFailed(m_device->CreatePlacedResource(
            m_sharedHeap.Get(),
            i * alignedDataSize,
            &crossAdapterDesc,
            D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
            nullptr,
            IID_PPV_ARGS(&m_positionBuffers[i])));
        const CD3DX12_CPU_DESCRIPTOR_HANDLE heapHandle(
            m_srvHeap->GetCPUDescriptorHandleForHeapStart(),
            UavParticlePos0 + i,
            m_srvUavDescriptorSize);
        m_device->CreateUnorderedAccessView(m_positionBuffers[i].Get(), nullptr, &uavDesc, heapHandle);
        ThrowIfFailed(m_device->CreateCommittedResource(
            &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
            D3D12_HEAP_FLAG_NONE,
            &CD3DX12_RESOURCE_DESC::Buffer(m_numParticles * sizeof(ParticleVelocity), D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS),
            D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
            nullptr,
            IID_PPV_ARGS(&m_velocityBuffers[i])));
        const CD3DX12_CPU_DESCRIPTOR_HANDLE velHeapHandle(
            m_srvHeap->GetCPUDescriptorHandleForHeapStart(),
            UavParticleVel0 + i,
            m_srvUavDescriptorSize);
        m_device->CreateUnorderedAccessView(m_velocityBuffers[i].Get(), nullptr, &velocityDesc, velHeapHandle);
    }
    const CD3DX12_CPU_DESCRIPTOR_HANDLE copyPosHandle(m_srvHeap->GetCPUDescriptorHandleForHeapStart(), UavParticlePos0Copy, m_srvUavDescriptorSize);
    m_device->CreateUnorderedAccessView(m_positionBuffers[0].Get(), nullptr, &uavDesc, copyPosHandle);
    const CD3DX12_CPU_DESCRIPTOR_HANDLE copyVelHandle(m_srvHeap->GetCPUDescriptorHandleForHeapStart(), UavParticleVel0Copy, m_srvUavDescriptorSize);
    m_device->CreateUnorderedAccessView(m_velocityBuffers[0].Get(), nullptr, &velocityDesc, copyVelHandle);
}
void Compute :: CreateSharedBuffers ( ) { const UINT dataSize = m_numParticles * sizeof ( Render :: Particle ) ; const D3D12_RESOURCE_DESC crossAdapterDesc = CD3DX12_RESOURCE_DESC :: Buffer ( dataSize , D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS | D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER ) ; const D3D12_RESOURCE_ALLOCATION_INFO textureInfo = m_device -> GetResourceAllocationInfo ( 0 , 1 , & crossAdapterDesc ) ; const UINT64 alignedDataSize = textureInfo . SizeInBytes ; const CD3DX12_HEAP_DESC heapDesc ( m_NUM_BUFFERS * alignedDataSize , D3D12_HEAP_TYPE_DEFAULT , 0 , D3D12_HEAP_FLAG_SHARED | D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER ) ; ThrowIfFailed ( m_device -> CreateHeap ( & heapDesc , IID_PPV_ARGS ( & m_sharedHeap ) ) ) ; ThrowIfFailed ( m_device -> CreateSharedHandle ( m_sharedHeap . Get ( ) , nullptr , GENERIC_ALL , 0 , & m_sharedHandles . m_heap ) ) ; m_sharedHandles . m_alignedDataSize = alignedDataSize ; D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = { } ; uavDesc . Format = DXGI_FORMAT_UNKNOWN ; uavDesc . ViewDimension = D3D12_UAV_DIMENSION_BUFFER ; uavDesc . Buffer . FirstElement = 0 ; uavDesc . Buffer . NumElements = m_numParticles ; uavDesc . Buffer . StructureByteStride = sizeof ( Render :: Particle ) ; uavDesc . Buffer . CounterOffsetInBytes = 0 ; uavDesc . Buffer . Flags = D3D12_BUFFER_UAV_FLAG_NONE ; D3D12_UNORDERED_ACCESS_VIEW_DESC velocityDesc = uavDesc ; velocityDesc . Buffer . StructureByteStride = sizeof ( ParticleVelocity ) ; for ( UINT i = 0 ; i < m_NUM_BUFFERS ; i ++ ) { ThrowIfFailed ( m_device -> CreatePlacedResource ( m_sharedHeap . Get ( ) , i * alignedDataSize , & crossAdapterDesc , D3D12_RESOURCE_STATE_UNORDERED_ACCESS , nullptr , IID_PPV_ARGS ( & m_positionBuffers [ i ] ) ) ) ; const CD3DX12_CPU_DESCRIPTOR_HANDLE heapHandle ( m_srvHeap -> GetCPUDescriptorHandleForHeapStart ( ) , UavParticlePos0 + i , m_srvUavDescriptorSize ) ; m_device -> CreateUnorderedAccessView ( m_positionBuffers [ i ] . Get ( ) , nullptr , & uavDesc , heapHandle ) ; ThrowIfFailed ( m_device -> CreateCommittedResource ( & CD3DX12_HEAP_PROPERTIES ( D3D12_HEAP_TYPE_DEFAULT ) , D3D12_HEAP_FLAG_NONE , & CD3DX12_RESOURCE_DESC :: Buffer ( m_numParticles * sizeof ( ParticleVelocity ) , D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS ) , D3D12_RESOURCE_STATE_UNORDERED_ACCESS , nullptr , IID_PPV_ARGS ( & m_velocityBuffers [ i ] ) ) ) ; const CD3DX12_CPU_DESCRIPTOR_HANDLE velHeapHandle ( m_srvHeap -> GetCPUDescriptorHandleForHeapStart ( ) , UavParticleVel0 + i , m_srvUavDescriptorSize ) ; m_device -> CreateUnorderedAccessView ( m_velocityBuffers [ i ] . Get ( ) , nullptr , & velocityDesc , velHeapHandle ) ; } const CD3DX12_CPU_DESCRIPTOR_HANDLE copyPosHandle ( m_srvHeap -> GetCPUDescriptorHandleForHeapStart ( ) , UavParticlePos0Copy , m_srvUavDescriptorSize ) ; m_device -> CreateUnorderedAccessView ( m_positionBuffers [ 0 ] . Get ( ) , nullptr , & uavDesc , copyPosHandle ) ; const CD3DX12_CPU_DESCRIPTOR_HANDLE copyVelHandle ( m_srvHeap -> GetCPUDescriptorHandleForHeapStart ( ) , UavParticleVel0Copy , m_srvUavDescriptorSize ) ; m_device -> CreateUnorderedAccessView ( m_velocityBuffers [ 0 ] . Get ( ) , nullptr , & velocityDesc , copyVelHandle ) ; }
Create two buffers in the GPU, each with a copy of the particles data
The compute shader reads from one and writes to the other
Create two buffers in the GPU each with a copy of the particles data The compute shader reads from one and writes to the other
/*
    Shared Heap notes from https://docs.microsoft.com/en-us/windows/win32/direct3d12/shared-heaps

    Cross adapter shared heaps enable multiple adapters to share data without the CPU marshaling the data between them.
    Cross-adapter shared resources are only supported in system memory.
    */ /*
    Why aren't we using D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS?
    MSDN:
    Use of this flag can compromise resource fences to perform waits, and prevents any compression being used with a resource.
    Cannot be used with D3D12_RESOURCE_DIMENSION_BUFFER; but buffers always have the properties represented by this flag.
    */ // An alias for 64KB. See documentation for D3D12_HEAP_DESC /*L"SHARED_HEAP"*/