通过CPU读取GPU资源数据



我如今正在学习DirectX11。而且我被困在计算着色器部分中。

所以我制作了四个资源和三个相应的视图。

  1. 不变的输入缓冲区= {1,1,1,1,1}/srv
  2. 不变的输入缓冲区= {2,2,2,2,2}/srv
  3. 输出缓冲区/无人机
  4. 用于阅读/无视图的分期缓冲区

我成功地创建了所有事物,并调度CS函数,并将数据从输出缓冲区复制到登台缓冲区,然后我读取/检查数据。

// INPUT BUFFER1--------------------------------------------------
const int dataSize = 5;
    D3D11_BUFFER_DESC vb_dest;
    vb_dest.ByteWidth = sizeof(float) * dataSize;
    vb_dest.StructureByteStride = sizeof(float);
    vb_dest.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    vb_dest.Usage = D3D11_USAGE_IMMUTABLE;
    vb_dest.CPUAccessFlags = 0;
    vb_dest.MiscFlags = 0;
    float v1_float[dataSize] = { 1,1,1,1,1 };
    D3D11_SUBRESOURCE_DATA v1_data;
    v1_data.pSysMem = static_cast<void*>(v1_float);
    device->CreateBuffer(
        &vb_dest,
        &v1_data,
        valueBuffer1.GetAddressOf());
    D3D11_SHADER_RESOURCE_VIEW_DESC srv_desc;
    srv_desc.Format = DXGI_FORMAT_R32_FLOAT;
    srv_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
    srv_desc.Buffer.FirstElement = 0;
    srv_desc.Buffer.NumElements = dataSize;
    srv_desc.Buffer.ElementWidth = sizeof(float);
    device->CreateShaderResourceView(
        valueBuffer1.Get(),
        &srv_desc,
        inputSRV1.GetAddressOf());
// INPUT BUFFER2-----------------------------------------------------------
    float v2_float[dataSize] = { 2,2,2,2,2 };
    D3D11_SUBRESOURCE_DATA v2_data;
    v2_data.pSysMem = static_cast<void*>(v2_float);
    device->CreateBuffer(
        &vb_dest,
        &v2_data,
        valueBuffer2.GetAddressOf());
    device->CreateShaderResourceView(
        valueBuffer2.Get(),
        &srv_desc,
        inputSRV2.GetAddressOf());
// OUTPUT BUFFER-----------------------------------------------------------
    D3D11_BUFFER_DESC ov_desc;
    ov_desc.ByteWidth = sizeof(float) * dataSize;
    ov_desc.StructureByteStride = sizeof(float);
    ov_desc.BindFlags = D3D11_BIND_UNORDERED_ACCESS;
    ov_desc.Usage = D3D11_USAGE_DEFAULT;
    ov_desc.CPUAccessFlags = 0;
    ov_desc.MiscFlags = 0;
    device->CreateBuffer(
        &ov_desc,
        nullptr,
        outputResource.GetAddressOf());
    D3D11_UNORDERED_ACCESS_VIEW_DESC outputUAV_desc;
    outputUAV_desc.Format = DXGI_FORMAT_R32_FLOAT;
    outputUAV_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
    outputUAV_desc.Buffer.FirstElement = 0;
    outputUAV_desc.Buffer.NumElements = dataSize;
    outputUAV_desc.Buffer.Flags = 0;
    device->CreateUnorderedAccessView(
        outputResource.Get(),
        &outputUAV_desc,
        outputUAV.GetAddressOf());
// BUFFER FOR COPY-----------------------------------------------------------
    D3D11_BUFFER_DESC rb_desc;
    rb_desc.ByteWidth = sizeof(float) * dataSize;
    rb_desc.StructureByteStride = sizeof(float);
    rb_desc.Usage = D3D11_USAGE_STAGING;
    rb_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
    rb_desc.BindFlags = 0;
    rb_desc.MiscFlags = 0;
    device->CreateBuffer(
        &rb_desc,
        nullptr,
        readResource.GetAddressOf());
// DISPATCH and COPY and GET DATA
    dContext->CSSetShaderResources(0, 1, inputSRV1.GetAddressOf());
    dContext->CSSetShaderResources(1, 1, inputSRV2.GetAddressOf());
    dContext->CSSetUnorderedAccessViews(0, 1, outputUAV.GetAddressOf(), nullptr);
    dContext->CSSetShader(cs.Get(), nullptr, 0);
    dContext->Dispatch(1, 1, 1);
    dContext->CopyResource(readResource.Get(), outputResource.Get());
    D3D11_MAPPED_SUBRESOURCE mappedResource2;
    ZeroMemory(&mappedResource2, sizeof(D3D11_MAPPED_SUBRESOURCE));
    R_CHECK(dContext->Map(readResource.Get(), 0, D3D11_MAP_READ, 0, &mappedResource2));
    float* data = static_cast<float*>(mappedResource2.pData);
    for (int i = 0; i < 5; ++i)
    {
        int a = data[i];
    }

这是计算着色器代码


StructuredBuffer<float> inputA : register(t0);
StructuredBuffer<float> inputB : register(t1);
RWStructuredBuffer<float> output : register(u0);
[numthreads(5, 1, 1)]
void main(int3 id : SV_DispatchThreadID)
{
    output[id.x] = inputA[id.x] + inputB[id.x];
}

在CS中,它添加了两个输入缓冲区数据,并将其存储到输出缓冲区中。因此,预期的答案将为{3,3,3,3,3}。

,但结果是{3,0,0,0,0}首先IDX具有正确的答案。

任何建议都会很棒。

 dContext->CopyResource(readResource.Get(), outputResource.Get());
    D3D11_MAPPED_SUBRESOURCE mappedResource2;
    ZeroMemory(&mappedResource2, sizeof(D3D11_MAPPED_SUBRESOURCE));
    R_CHECK(dContext->Map(readResource.Get(), 0, D3D11_MAP_READ, 0, &mappedResource2));
    float* data = static_cast<float*>(mappedResource2.pData);
    for (int i = 0; i < 5; ++i)
    {
        int a = data[i];
    }

此代码应该是这样的。

CopyResource();
Map();
Declare and allocate 'data'
zeromemory(data);
memcopy(data, resource's pointer);
unMap();

出于某种原因,我必须使用Memcopy,而不是直接使用映射的指针读取资源。

相关内容

  • 没有找到相关文章

最新更新