ThraceShah
ThraceShah

Reputation: 1

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;
}

I believe the correct output should be "{2,2,2}, {5,5,5}, {8,8,8}", but the result I got was "{2,5,8}, {0,0,0}, {0,0,0}". Can you help me point out where the error occurred? When I modified the hlsl output from yyy to xyz, I obtained results {1,4,7}, {0,0,0}, {0,0,0}. Therefore, I believe that the input and calculation results of the compute shader are correct, but I encountered an error when obtaining the results from the GPU, but I couldn't find the error.

Upvotes: 0

Views: 63

Answers (0)

Related Questions