🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Read back texture to 1D buffer in dx12

Started by
0 comments, last by bdm0227 3 weeks ago

I want to copy a small two-dimensional output from a compute shader into a one-dimensional readback buffer. However, when I run it, the program crashes.

D3D12_COMMAND_QUEUE_DESC cqDesc = {};
    cqDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
    cqDesc.Type = D3D12_COMMAND_LIST_TYPE_COMPUTE;
    device->CreateCommandQueue(&cqDesc, IID_PPV_ARGS(&commandQueue));
    device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COMPUTE, IID_PPV_ARGS(&commandAllocator));
    device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COMPUTE, commandAllocator, NULL, IID_PPV_ARGS(&commandList));

    D3D12_COMMAND_QUEUE_DESC c2qDesc = {};
    c2qDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
    c2qDesc.Type = D3D12_COMMAND_LIST_TYPE_COPY;
    device->CreateCommandQueue(&c2qDesc, IID_PPV_ARGS(&copyCmdQueue));
    device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COPY, IID_PPV_ARGS(&copyCmdAllocator));
    device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COPY, copyCmdAllocator, NULL, IID_PPV_ARGS(&copyCmdList));

I'm using graphics, compute, copy queues and 2 fences. compute, copy queues are sharing 1 fence and graphics is separated.

D3D12_RESOURCE_DESC desc = CD3DX12_RESOURCE_DESC::Tex3D(DXGI_FORMAT_R32_FLOAT, w, h, d);
    D3D12_UAV_DIMENSION UavDimension = D3D12_UAV_DIMENSION_TEXTURE3D;

    if (d == 0) {
        desc = CD3DX12_RESOURCE_DESC::Tex2D(DXGI_FORMAT_R32_FLOAT, w, h);
        UavDimension = D3D12_UAV_DIMENSION_TEXTURE2D;

        if (h == 0) {
            desc = CD3DX12_RESOURCE_DESC::Tex1D(DXGI_FORMAT_R32_FLOAT, w);
            UavDimension = D3D12_UAV_DIMENSION_TEXTURE1D;
        }
    }
    desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
    
    device->CreateCommittedResource(
        &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
        D3D12_HEAP_FLAG_NONE,
        &desc,
        D3D12_RESOURCE_STATE_COMMON,
        nullptr,
        IID_PPV_ARGS(&buf));

    commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(buf, D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_UNORDERED_ACCESS));

This is part of initialize function for every compute buffer. Copy source is 4X2size DXGI_FORMAT_R32_FLOAT format 2D buffer.

D3D12_RESOURCE_DESC AboutSrc = SrcBuf->GetDesc();
    size_t w = AboutSrc.Width;
    size_t h = AboutSrc.Height;
    size_t d = AboutSrc.DepthOrArraySize;

device->CreateCommittedResource(
        &CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_READBACK),
        D3D12_HEAP_FLAG_NONE,
        &CD3DX12_RESOURCE_DESC::Buffer(w * h * d * sizeof(float)),
        D3D12_RESOURCE_STATE_COPY_DEST,
        nullptr,
        IID_PPV_ARGS(&UplBuf));

commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(SrcBuf, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE));
    WaitForPreviousCompute();

    //copyCmdList->CopyResource(UplBuf, SrcBuf);
    //copyCmdList->CopyBufferRegion(UplBuf, 0, SrcBuf, 0, 16);

    D3D12_PLACED_SUBRESOURCE_FOOTPRINT PlacedFootprint = {};
    PlacedFootprint.Offset = 0;
    PlacedFootprint.Footprint.Format = DXGI_FORMAT_UNKNOWN;
    PlacedFootprint.Footprint.Width = w * h * d * sizeof(float);
    PlacedFootprint.Footprint.Height = 1;
    PlacedFootprint.Footprint.Depth = 1;
    PlacedFootprint.Footprint.RowPitch = 256;

    D3D12_TEXTURE_COPY_LOCATION dst = { UplBuf, D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, PlacedFootprint };
    D3D12_TEXTURE_COPY_LOCATION src = { SrcBuf, D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, 0 };
    copyCmdList->CopyTextureRegion(&dst, 0, 0, 0, &src, nullptr);
    WaitForPreviousCopy();

    commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(SrcBuf, D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS));
    WaitForPreviousCompute();

WaitForPreviousCompute and WaitForPreviousCopy include executing command List.

I haven't been able to pinpoint the exact point of the problem yet, so where is the problem?

Advertisement