2014-10-19 48 views
1

我似乎无法找到让我自己读取来自AMP数组的数据的方法。使用C++读取缓冲区数据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); 

基本上它应该从缓冲区中的所有数据写入到载体

现在我知道我应该把我的访问标志,但我似乎无法做到这一点。我写在下面的函数在我的initialise:

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

但是它打破,并出现以下错误

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

我不知道这意味着什么,如果我试图将其设置阅读和写作,没有通过测试?它也适用于我尝试的任何访问类型。

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

回答

0

您可以创建一个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或更高功能级别的ID3D11设备接口。 C++ AMP accelerator_views可以从多个线程访问,因此不应使用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章。