Buffer 用CPU读取GPU资源数据

Buffer 用CPU读取GPU资源数据,buffer,directx,gpgpu,staging,directcompute,Buffer,Directx,Gpgpu,Staging,Directcompute,这些天我在学习directx11。我一直被困在计算着色器部分 所以我提出了四个资源和三个相应的观点 不可变输入缓冲区={1,1,1,1}/SRV 不可变输入缓冲区={2,2,2,2}/SRV 输出缓冲器/无人机 用于读取/无视图的暂存缓冲区 我成功地创建了所有东西,并分派了cs函数,将数据从输出缓冲区复制到暂存缓冲区,然后读取/检查数据 // INPUT BUFFER1-------------------------------------------------- const int dat

这些天我在学习directx11。我一直被困在计算着色器部分

所以我提出了四个资源和三个相应的观点

  • 不可变输入缓冲区={1,1,1,1}/SRV
  • 不可变输入缓冲区={2,2,2,2}/SRV
  • 输出缓冲器/无人机
  • 用于读取/无视图的暂存缓冲区
  • 我成功地创建了所有东西,并分派了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];
        }
    
    //输入缓冲区1--------------------------------------------------
    常数int dataSize=5;
    D3D11_BUFFER_DESC vb_dest;
    vb_dest.ByteWidth=sizeof(float)*数据大小;
    vb_dest.StructureByteStride=sizeof(float);
    vb_dest.BindFlags=D3D11_BIND_SHADER_RESOURCE;
    vb_dest.Usage=D3D11_Usage_不可变;
    vb_dest.CPUAccessFlags=0;
    vb_dest.miscsflags=0;
    float v1_float[dataSize]={1,1,1,1};
    D3D11_子资源_数据v1_数据;
    v1_data.psysem=静态_转换(v1_浮动);
    设备->创建缓冲区(
    &vb_dest,
    &v1_数据,
    valueBuffer1.GetAddressOf());
    D3D11_着色器_资源_视图_描述srv_描述;
    srv_desc.Format=DXGI_Format_R32_FLOAT;
    srv_desc.ViewDimension=D3D11_srv_DIMENSION_BUFFER;
    srv_desc.Buffer.FirstElement=0;
    srv_desc.Buffer.NumElements=数据大小;
    srv_desc.Buffer.ElementWidth=sizeof(float);
    设备->CreateShaderResourceView(
    valueBuffer1.Get(),
    &srv_desc,
    inputSRV1.GetAddressOf());
    //输入缓冲区2-----------------------------------------------------------
    float v2_float[dataSize]={2,2,2,2};
    D3D11_子资源_数据v2_数据;
    v2_data.psysem=静态_转换(v2_浮动);
    设备->创建缓冲区(
    &vb_dest,
    &v2_数据,
    valueBuffer2.GetAddressOf());
    设备->CreateShaderResourceView(
    valueBuffer2.Get(),
    &srv_desc,
    inputSRV2.GetAddressOf());
    //输出缓冲区-----------------------------------------------------------
    D3D11_BUFFER_DESC ov_DESC;
    ov_desc.ByteWidth=sizeof(float)*数据大小;
    ov_desc.StructureByteStride=sizeof(float);
    ov_desc.BindFlags=D3D11_BIND_无序访问;
    ov_desc.Usage=D3D11_Usage_默认值;
    ov_desc.CPUAccessFlags=0;
    ov_desc.miscsflags=0;
    设备->创建缓冲区(
    &ov_desc,
    nullptr,
    outputResource.GetAddressOf());
    D3D11 \u无序\u访问\u查看\u描述输出\u描述;
    outputUAV_desc.Format=DXGI_Format_R32_FLOAT;
    outputUAV_desc.ViewDimension=D3D11_UAV_DIMENSION_BUFFER;
    outputUAV_desc.Buffer.FirstElement=0;
    outputUAV_desc.Buffer.NumElements=数据大小;
    outputUAV_desc.Buffer.Flags=0;
    设备->创建无序访问视图(
    outputResource.Get(),
    &输出无人机描述,
    outputUAV.GetAddressOf());
    //复制缓冲区-----------------------------------------------------------
    D3D11_BUFFER_DESC rb_DESC;
    rb_desc.ByteWidth=sizeof(float)*数据大小;
    rb_desc.StructureByteStride=sizeof(float);
    rb_desc.Usage=D3D11_Usage_STAGING;
    rb_desc.CPUAccessFlags=D3D11_CPU_访问_读取;
    rb_desc.BindFlags=0;
    rb_desc.miscsflags=0;
    设备->创建缓冲区(
    &rb_desc,
    nullptr,
    readResource.GetAddressOf());
    //发送、复制并获取数据
    dContext->CSSetShaderResources(0,1,inputSRV1.GetAddressOf());
    dContext->CSSetShaderResources(1,1,inputSRV2.GetAddressOf());
    dContext->cssetUnorderedAccessView(0,1,outputUAV.GetAddressOf(),nullptr);
    dContext->CSSetShader(cs.Get(),nullptr,0);
    dContext->Dispatch(1,1,1);
    dContext->copyrource(readResource.Get(),outputResource.Get());
    D3D11_映射_子资源mappedResource2;
    零内存(&mappedResource2,sizeof(D3D11_映射_子资源));
    R_检查(dContext->Map(readResource.Get(),0,D3D11_Map_READ,0,&mappedResource2));
    float*data=static_cast(mappedResource2.pData);
    对于(int i=0;i<5;++i)
    {
    int a=数据[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];
    }
    
    
    StructuredBuffer输入:寄存器(t0);
    StructuredBuffer输入B:寄存器(t1);
    RWStructuredBuffer输出:寄存器(u0);
    [numthreads(5,1,1)]
    void main(int3 id:SV_DispatchThreadID)
    {
    输出[id.x]=inputA[id.x]+inputB[id.x];
    }
    
    在CS中,它添加两个输入缓冲区数据并存储到输出缓冲区。 所以预期的答案是{3,3,3,3}

    但结果是{3,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];
        }
    
    出于某种原因,我必须使用memcopy,而不是直接用从映射中获得的指针读取资源

    出于某种原因,我必须使用memcopy,而不是直接用从映射中获得的指针读取资源

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