DirectX 11 - 计算着色器,将数据从 GPU 复制到 CPU

DirectX 11 - Compute Shader, copy data from the GPU to the CPU

本文关键字:数据 GPU 复制 CPU 计算 DirectX      更新时间:2023-10-16

我刚刚开始使用直接计算,试图将我一直在做的流体模拟转移到GPU上。我在这里发现了一个非常相似(如果不是相同(的问题,但是似乎我的问题的解决方法与他们的解决方案不同;我确实有我的复制资源是正确的方式!与粘贴的问题一样,从 GPU 复制回来时,我只会得到一个填充 0 的缓冲区。我真的看不到错误,因为我不明白我怎么能超出界限。对于即将发生的大量代码粘贴,我将道歉,但我想确保我没有弄错任何设置。

输出缓冲区、无人机和系统缓冲区设置

    outputDesc.Usage = D3D11_USAGE_DEFAULT;
	outputDesc.BindFlags = D3D11_BIND_UNORDERED_ACCESS;
	outputDesc.ByteWidth = sizeof(BoundaryConditions) * numElements;
	outputDesc.CPUAccessFlags = 0;
	outputDesc.StructureByteStride = sizeof(BoundaryConditions);
	outputDesc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;	
	result =_device->CreateBuffer(&outputDesc, 0, &m_outputBuffer);
	outputDesc.Usage = D3D11_USAGE_STAGING;
	outputDesc.BindFlags = 0;
	outputDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
	result = _device->CreateBuffer(&outputDesc, 0, &m_outputresult);
	D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
	uavDesc.Format = DXGI_FORMAT_UNKNOWN;
	uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
	uavDesc.Buffer.FirstElement = 0;
	uavDesc.Buffer.Flags = 0;
	uavDesc.Buffer.NumElements = numElements;
	result =_device->CreateUnorderedAccessView(m_outputBuffer, &uavDesc, &m_BoundaryConditionsUAV);

在我的帧循环中运行着色器

HRESULT result;
	D3D11_MAPPED_SUBRESOURCE mappedResource;
	_deviceContext->CSSetShader(m_BoundaryConditionsCS, nullptr, 0);
	_deviceContext->CSSetUnorderedAccessViews(0, 1, &m_BoundaryConditionsUAV, 0);
	_deviceContext->Dispatch(1, 1, 1);
	// Unbind output from compute shader
	ID3D11UnorderedAccessView* nullUAV[] = { NULL };
	_deviceContext->CSSetUnorderedAccessViews(0, 1, nullUAV, 0);
	// Disable Compute Shader
	_deviceContext->CSSetShader(nullptr, nullptr, 0);
	_deviceContext->CopyResource(m_outputresult, m_outputBuffer);
	D3D11_MAPPED_SUBRESOURCE mappedData;
	result = _deviceContext->Map(m_outputresult, 0, D3D11_MAP_READ, 0, &mappedData);
	BoundaryConditions* newbc = reinterpret_cast<BoundaryConditions*>(mappedData.pData);
	
	for (int i = 0; i < 4; i++)
	{
		Debug::Instance()->Log(newbc[i].x.x);
	}
	_deviceContext->Unmap(m_outputresult, 0);

高空

struct BoundaryConditions
{
	float3 x;
	float3 y;
};
RWStructuredBuffer<BoundaryConditions> _boundaryConditions;
[numthreads(4, 1, 1)]
void ComputeBoundaryConditions(int3 id : SV_DispatchThreadID)
{
	_boundaryConditions[id.x].x = float3(id.x,id.y,id.z);
}

我在开始帧之后和结束帧之前调度计算着色器。我已经尝试过将着色器调度调用移动到结束场景之外和当前 ect 之前,但似乎没有什么影响这个过程。似乎想不通这个!

圣烟 我修复了错误!我正在为不同的 ID3D11ComputeShader 指针创建计算着色器!D:像魅力一样工作!对不起,谢谢亚当!