提问人:ThraceShah 提问时间:8/16/2023 更新时间:8/16/2023 访问量:28
如何在dx11中获取计算着色器的正确输出,我使用SharpDx
How to get correct output of compute shader in dx11,I use SharpDx
问:
float[] buffer = new float[]{1,2,3,4,5,6,7,8,9};
var vertexArray = MemoryMarshal.Cast<float, Vector3>(buffer).ToArray();
var device = new Device(DriverType.Hardware, DeviceCreationFlags.Debug);
var context = device.ImmediateContext;
// 编译计算着色器
var faceCsFile = Path.Combine(AppContext.BaseDirectory, "HLSL/Face_CS.hlsl");
var shaderBytecode = ShaderBytecode.CompileFromFile(faceCsFile, "CS", "cs_5_0");
var computeShader = new ComputeShader(device, shaderBytecode);
shaderBytecode.Dispose();
var inputDesc = new BufferDescription()
{SizeInBytes = SharpDX.Utilities.SizeOf<Vector3>() * vertexArray.Length,
Usage = ResourceUsage.Default,
BindFlags = BindFlags.ShaderResource | BindFlags.UnorderedAccess,
OptionFlags = ResourceOptionFlags.BufferStructured,
StructureByteStride = SharpDX.Utilities.SizeOf<Vector3>(),};
var verticeBuffer = Buffer.Create(device, vertexArray, inputDesc);
device.ImmediateContext.UnmapSubresource(verticeBuffer, 0);
var srvDesc = new ShaderResourceViewDescription()
{Format = SharpDX.DXGI.Format.Unknown,
Dimension = ShaderResourceViewDimension.Buffer,
BufferEx = new ShaderResourceViewDescription.ExtendedBufferResource()
{
FirstElement = 0,
ElementCount = vertexArray.Length,
Flags = ShaderResourceViewExtendedBufferFlags.None
} };
var vertexBufferView = new ShaderResourceView(device, verticeBuffer, srvDesc);
context.ComputeShader.SetShaderResource(0, vertexBufferView);
// 将输入和输出缓冲区绑定到计算着色器上
context.ComputeShader.Set(computeShader);
var dataOut = new Vector3[vertexArray.Length];
var outDes = new BufferDescription()
{SizeInBytes = SharpDX.Utilities.SizeOf<Vector3>() * vertexArray.Length,
Usage = ResourceUsage.Default,
BindFlags = BindFlags.UnorderedAccess,
OptionFlags = ResourceOptionFlags.BufferStructured,
StructureByteStride = SharpDX.Utilities.SizeOf<Vector3>(),};
var bufferOut = Buffer.Create(device, dataOut, outDes);
// 创建用于指定着色器输出的UAV
var uavDesc = new UnorderedAccessViewDescription()
{Format = SharpDX.DXGI.Format.Unknown,
Dimension = UnorderedAccessViewDimension.Buffer,
Buffer = new UnorderedAccessViewDescription.BufferResource()
{ElementCount = vertexArray.Length,}};
var bufferOutView = new UnorderedAccessView(device, bufferOut, uavDesc);
context.ComputeShader.SetUnorderedAccessView(0, bufferOutView);
int count = (vertexArray.Length + 1023) / 1024;
context.Dispatch(count, 1, 1);// 启动计算着色器
var stagingBuffer = new Buffer(device, new BufferDescription
{BindFlags = BindFlags.None,
CpuAccessFlags = CpuAccessFlags.Read,
OptionFlags = ResourceOptionFlags.None,
SizeInBytes = dataOut.Length * SharpDX.Utilities.SizeOf<Vector3>(),
Usage = ResourceUsage.Staging});// 创建一个暂存缓冲区
context.CopyResource(bufferOut, stagingBuffer);// 将输出缓冲区的内容复制到暂存缓冲区中
// 将暂存缓冲区映射到内存中
var dataBox = context.MapSubresource(stagingBuffer, 0, MapMode.Read, SharpDX.Direct3D11.MapFlags.None);
Span<Vector3> result;
unsafe{result = new Span<Vector3>((void*)dataBox.DataPointer, dataOut.Length);}// 读取数据
context.UnmapSubresource(stagingBuffer, 0);// 取消映射
foreach (var vec in result.ToArray())
Console.WriteLine(vec);
StructuredBuffer<float3> Vertex : register(t0);
RWBuffer<float3> Out : register(u0);
[numthreads(1024, 1, 1)]
void CS(uint3 DTid : SV_DispatchThreadID)
{
uint id = DTid.x;
Out[id]=Vertex[id].yyy;
}
我相信正确的输出应该是“{2,2,2},{5,5,5},{8,8,8}”,但我得到的结果是“{2,5,8},{0,0,0},{0,0,0}”。你能帮我指出错误发生的位置吗? 当我将 hlsl 输出从 yyy 修改为 xyz 时,我获得了结果 {1,4,7}, {0,0,0}, {0,0,0}。因此,我认为计算着色器的输入和计算结果是正确的,但是在从GPU获取结果时遇到了错误,但是找不到错误。
答: 暂无答案
评论