none
Attempting to dispatch to multiple compute shaders sequentially through DirectX12 api, but encountering mutations in the UAV when I test on Microsoft Basic Render Driver. Is there a flaw in my code/Is there a proper way to do this?

    Question

  • To expand on the title, I have a number of compute pipeline states; I want to run the first (which then writes to a UAV), then the next (which reads from the UAV, does some operations, then writes back to the UAV), etc.

    The problem I'm encountering is that when I test this on WARP (Microsoft Basic Render Driver), I find that my UAV is mutating the moment I dispatch--specifically, I'm seeing an effect where all the uint4s in my UAV are set to whatever is stored in the first uint4.  So, for example, if the first 8 uints in the UAV at the end of the first dispatch are

    0x00000000, 0x00000001, 0x00000002, 0x00000003,

    0x00000004, 0x00000005, 0x00000006, 0x00000007

    then at the start of my second dispatch, the UAV changes to:

    0x00000000, 0x00000001, 0x00000002, 0x00000003,

    0x00000000, 0x00000001, 0x00000002, 0x00000003,

    This effect doesn't occur when running on my own hardware GPU.

    Here is some relevant calling code:

    IndividualDispatch(
        this->prologueState.Get(),
        indexLog2);
    
    BetweenDispatches();
    
    IndividualDispatch(
        this->epilogueState.Get(),
        indexLog2);

    ...and here are some relevant function definitions:

    void IndividualDispatch(
        _In_ ID3D12PipelineState* shader,
        const uint8_t indexLog2)
    {
        this->directCommandList->Reset(
            this->directCommandAllocator.Get(),
            shader);
    
        this->directCommandList->SetComputeRootSignature(
            this->rootSignature.Get());
    
        this->directCommandList->SetComputeRootConstantBufferView(
            1,
            this->precomputeBuffer->GetGPUVirtualAddress());
    
        this->directCommandList->SetComputeRootConstantBufferView(
            0,
            this->bufferInfoBuffer->GetGPUVirtualAddress());
    
        this->directCommandList->SetComputeRootUnorderedAccessView(
            2,
            this->uavBuffer->GetGPUVirtualAddress());
    
        this->Dc12HasherImpl::Dispatch(
            this->directCommandList.Get(),
            indexLog2);
    }

    void BetweenDispatches() { this->directCommandList->Close(); DC12::ExecuteCommandList( this->directCommandQueue.Get(), this->directCommandList.Get()); }

    static inline void ExecuteCommandList(
        _In_ ID3D12CommandQueue* pCommandQueue,
        _In_ ID3D12CommandList* pCommandList)
    {
        pCommandQueue->ExecuteCommandLists(
            1,
            &pCommandList);
    }
    void DC12HasherImpl::Dispatch(
        ID3D12GraphicsCommandList* commandList,
        _In_ const uint8_t countLog2) NOEXCEPT
    {
        const uint8_t threadGroupLog2 =
            this->threadGroupLog2;
    
        uint8_t x = 0;
    
        if (countLog2 > threadGroupLog2)
        {
            x = countLog2 - threadGroupLog2;
        }
    
        uint8_t y = 0;
    
        if (x > DcHelper::MaxDimensionLog2)
        {
            y = x - DcHelper::MaxDimensionLog2;
    
            x = DcHelper::MaxDimensionLog2;
        }
    
        commandList->Dispatch(
            1u << x,
            1u << y,
            1u);
    }


    Am I misusing the API?  Is there perhaps a more canonical sequence of DX12 instructions to accomplish my goal here?  ...is there a bug in the DirectX12 api (I'm assuming this is unlikely)?


    Sunday, March 17, 2019 4:24 PM