чтение данных ресурса GPU процессором - PullRequest
1 голос
/ 10 мая 2019

Я изучаю Directx11 в эти дни.и я застрял в секции вычислительных шейдеров.

, поэтому я создал четыре ресурса и три соответствующих представления.

  1. неизменный входной буфер = {1,1,1,1,1}/ SRV
  2. неизменный входной буфер = {2,2,2,2,2} / SRV
  3. выходной буфер / UAV
  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 имеет правильный ответ.

любой совет был бы удивительным.

1 Ответ

0 голосов
/ 21 мая 2019
 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 вместо того, чтобы просто читать ресурс непосредственно с указателем, который я получаю из отображения.

...