Buffer 用CPU读取GPU资源数据
这些天我在学习directx11。我一直被困在计算着色器部分 所以我提出了四个资源和三个相应的观点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
// 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();