【问题标题】:Reading Buffer Data using C++ AMP使用 C++ AMP 读取缓冲区数据
【发布时间】:2014-10-19 07:08:15
【问题描述】:

我似乎找不到让自己从我的 AMP 数组中读取数据的方法。

我希望能够做的是获取我的缓冲区,将其复制到向量中,然后使用该向量。我知道我应该设置 CPU 访问标志,但是我在这样做时遇到了麻烦。

首先,这就是我尝试访问缓冲区的方式。我先把它放在这里,以防我做了不应该做的事情。也许有一个我错过的内置函数可以为我做这件事?

std::vector<Pticle> vecParticles;
    ID3D11Buffer* pBuffer = reinterpret_cast<ID3D11Buffer *>(concurrency::direct3d::get_buffer(m_arrParticles));
    D3D11_MAPPED_SUBRESOURCE MappedResource;
    m_pDeviceContext->Map(pBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource);
    {
        auto pData = (Pticle*)MappedResource.pData;
        for (unsigned i = 0; i < m_uiNumParticles; ++i)
        {
            vecParticles.push_back(pData[i]);
        }
    }
    m_pDeviceContext->Unmap(pBuffer, 0);

基本上它应该将缓冲区中的所有数据写入向量中

现在我知道我应该设置我的访问标志,但我似乎做不到。我在初始化时写了以下函数:

m_Accelerator.set_default_cpu_access_type(concurrency::access_type::access_type_read_write);

但是它会中断,并出现以下错误

"Invalid access_type specified. accelerator does not support zero copy."

我不确定这意味着什么,如果我尝试将其设置为读写,它没有通过测试吗?它也适用于我尝试的任何访问类型。

如何设置它以便从缓冲区读取数据?

【问题讨论】:

    标签: c++ directx c++-amp


    【解决方案1】:

    您可以创建一个 DX 缓冲区,然后使用 make_array 创建一个 C++AMP array

    HRESULT hr = S_OK;
    UINT bufferSize = 1024;
    D3D11_BUFFER_DESC bufferDesc =
    {
        bufferSize * sizeof(float),
        D3D11_USAGE_DEFAULT,
        D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_SHADER_RESOURCE |
            D3D11_BIND_UNORDERED_ACCESS,
        0 /* no CPU access */,
        D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS /* misc flags */,
        sizeof(float)
    };
    D3D11_SUBRESOURCE_DATA resourceData;
    
    ZeroMemory(&resourceData, sizeof(D3D11_SUBRESOURCE_DATA));
    std::vector<float> vertices(bufferSize, 1.0f);
    resourceData.pSysMem = &vertices[0];
    CComPtr<ID3D11Buffer> buffer;
    hr = device->CreateBuffer(&bufferDesc, &resourceData, &buffer);
    assert(SUCCEEDED(hr));
    
    array<float, 1> arr = make_array<float, 1>(extent<1>(bufferSize), dxView, buffer);
    std::wcout << "Created array<float,1> on " 
        << arr.accelerator_view.accelerator.description << std::endl;
    

    请注意,设备和缓冲区必须满足一组要求才能正常工作。 Direct3D 设备必须实现具有 D3D_FEATURE_LEVEL_11_0 或更高功能级别的 ID3D11Deviceinterface。可以从多个线程访问 C++ AMP 加速器视图,因此不应使用 D3D11_CREATE_DEVICE_FLAG D3D11_CREATE_DEVICE_SINGLETHREADED 集来创建设备。

    Direct3D 缓冲区必须实现 ID3D11Buffer 接口。它必须支持原始视图 (D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS) 并允许 SHADER_RESOURCE 和 UNORDERED_ACCESS绑定。缓冲区本身的大小必须正确,即范围的大小 乘以缓冲区类型的大小。

    您可以使用create_accelerator_view 创建 C++ AMP accelerator,如下所示。

    HRESULT hr = S_OK;
    UINT createDeviceFlags = 0;
    #ifdef _DEBUG
        createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
    #endif
    std::array<D3D_FEATURE_LEVEL, 1> featureLevels = { D3D_FEATURE_LEVEL_11_0 };
    CComPtr<ID3D11Device> device;
    D3D_FEATURE_LEVEL featureLevel;
    CComPtr<ID3D11DeviceContext> immediateContext;
    hr = D3D11CreateDevice(nullptr /* default adapter */,
        D3D_DRIVER_TYPE_HARDWARE,
        nullptr /* No software rasterizer */,
        createDeviceFlags,
        featureLevels.data(),
        UINT(featureLevels.size()),
        D3D11_SDK_VERSION,
        &device,
        &featureLevel,
        &immediateContext);
    assert(SUCCEEDED(hr));
    
    accelerator_view dxView = create_accelerator_view(device);
    

    这一切都取自C++ AMP Book的第11章。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      相关资源
      最近更新 更多