Ejemplo n.º 1
0
        static void Main(string[] args)
        {
            const int elementCount = 16;
            const int bufferSizeInBytes = elementCount * sizeof(float);

            D3D.Device device = new D3D.Device(D3D.DriverType.Hardware, D3D.DeviceCreationFlags.Debug);

            // The input to the computation will be a constant buffer containing
            // integers (in floating point representation) from 1 to numberOfElements,
            // inclusive. The compute shader itself will double these values and write
            // them to the output buffer.
            D3D.BufferDescription inputBufferDescription = new D3D.BufferDescription
            {
                BindFlags = D3D.BindFlags.ConstantBuffer,
                CpuAccessFlags = D3D.CpuAccessFlags.Write,
                OptionFlags = D3D.ResourceOptionFlags.None,
                SizeInBytes = bufferSizeInBytes,
                StructureByteStride = sizeof(float),
                Usage = D3D.ResourceUsage.Dynamic,
            };
            D3D.Buffer inputBuffer = new D3D.Buffer(device, inputBufferDescription);
            DataBox input = device.ImmediateContext.MapSubresource(inputBuffer, 0, bufferSizeInBytes, D3D.MapMode.WriteDiscard, D3D.MapFlags.None);
            for (int value = 1; value <= elementCount; ++value)
                input.Data.Write((float)value);
            device.ImmediateContext.UnmapSubresource(inputBuffer, 0);

            // A staging buffer is used to copy data between the CPU and GPU; the output
            // buffer (which gets the computation results) cannot be mapped directly.
            D3D.BufferDescription stagingBufferDescription = new D3D.BufferDescription
            {
                BindFlags = D3D.BindFlags.None,
                CpuAccessFlags = D3D.CpuAccessFlags.Read,
                OptionFlags = D3D.ResourceOptionFlags.StructuredBuffer,
                SizeInBytes = bufferSizeInBytes,
                StructureByteStride = sizeof(float),
                Usage = D3D.ResourceUsage.Staging,
            };
            D3D.Buffer stagingBuffer = new D3D.Buffer(device, stagingBufferDescription);

            // The output buffer itself, and the view required to bind it to the pipeline.
            D3D.BufferDescription outputBufferDescription = new D3D.BufferDescription
            {
                BindFlags = D3D.BindFlags.UnorderedAccess | D3D.BindFlags.ShaderResource,
                OptionFlags = D3D.ResourceOptionFlags.StructuredBuffer,
                SizeInBytes = bufferSizeInBytes,
                StructureByteStride = sizeof(float),
                Usage = D3D.ResourceUsage.Default,
            };
            D3D.Buffer outputBuffer = new D3D.Buffer(device, outputBufferDescription);
            D3D.UnorderedAccessViewDescription outputViewDescription = new D3D.UnorderedAccessViewDescription
            {
                ElementCount = elementCount,
                Format = DXGI.Format.Unknown,
                Dimension = D3D.UnorderedAccessViewDimension.Buffer
            };
            D3D.UnorderedAccessView outputView = new D3D.UnorderedAccessView(device, outputBuffer, outputViewDescription);

            // Compile the shader.
            ShaderBytecode computeShaderCode = ShaderBytecode.CompileFromFile("BasicComputeShader.hlsl", "main", "cs_4_0", ShaderFlags.None, EffectFlags.None);
            D3D.ComputeShader computeShader = new D3D.ComputeShader(device, computeShaderCode);

            device.ImmediateContext.ComputeShader.Set(computeShader);
            device.ImmediateContext.ComputeShader.SetUnorderedAccessView(outputView, 0);
            device.ImmediateContext.ComputeShader.SetConstantBuffer(inputBuffer, 0);

            // Compute shaders execute on multiple threads at the same time. Those execution
            // threads are grouped; Dispatch() indicates how many groups in the X, Y and Z
            // dimension will be utilized. The shader itself specified how many threads per
            // group (also in X, Y and Z dimensions) to use via the [numthreads] attribute.
            // In this sample, one thread group will be used with 16 threads, each thread
            // will process one element of the input data.
            device.ImmediateContext.Dispatch(1, 1, 1);

            device.ImmediateContext.CopyResource(outputBuffer, stagingBuffer);
            DataBox output = device.ImmediateContext.MapSubresource(stagingBuffer, 0, sizeof(float) * elementCount, D3D.MapMode.Read, D3D.MapFlags.None);

            Console.Write("Results:");
            for (int index = 0; index < elementCount; ++index)
                Console.Write(" {0}", output.Data.Read<float>());
            device.ImmediateContext.UnmapSubresource(outputBuffer, 0);
            Console.WriteLine();

            computeShader.Dispose();
            outputView.Dispose();
            outputBuffer.Dispose();
            stagingBuffer.Dispose();
            inputBuffer.Dispose();
            device.Dispose();
        }
Ejemplo n.º 2
0
        static void Main(string[] args)
        {
            const int elementCount      = 16;
            const int bufferSizeInBytes = elementCount * sizeof(float);

            D3D.Device device = new D3D.Device(D3D.DriverType.Hardware, D3D.DeviceCreationFlags.Debug);

            // The input to the computation will be a constant buffer containing
            // integers (in floating point representation) from 1 to numberOfElements,
            // inclusive. The compute shader itself will double these values and write
            // them to the output buffer.
            D3D.BufferDescription inputBufferDescription = new D3D.BufferDescription
            {
                BindFlags           = D3D.BindFlags.ConstantBuffer,
                CpuAccessFlags      = D3D.CpuAccessFlags.Write,
                OptionFlags         = D3D.ResourceOptionFlags.None,
                SizeInBytes         = bufferSizeInBytes,
                StructureByteStride = sizeof(float),
                Usage = D3D.ResourceUsage.Dynamic,
            };
            D3D.Buffer inputBuffer = new D3D.Buffer(device, inputBufferDescription);
            DataBox    input       = device.ImmediateContext.MapSubresource(inputBuffer, D3D.MapMode.WriteDiscard, D3D.MapFlags.None);

            for (int value = 1; value <= elementCount; ++value)
            {
                input.Data.Write((float)value);
            }
            device.ImmediateContext.UnmapSubresource(inputBuffer, 0);

            // A staging buffer is used to copy data between the CPU and GPU; the output
            // buffer (which gets the computation results) cannot be mapped directly.
            D3D.BufferDescription stagingBufferDescription = new D3D.BufferDescription
            {
                BindFlags           = D3D.BindFlags.None,
                CpuAccessFlags      = D3D.CpuAccessFlags.Read,
                OptionFlags         = D3D.ResourceOptionFlags.StructuredBuffer,
                SizeInBytes         = bufferSizeInBytes,
                StructureByteStride = sizeof(float),
                Usage = D3D.ResourceUsage.Staging,
            };
            D3D.Buffer stagingBuffer = new D3D.Buffer(device, stagingBufferDescription);

            // The output buffer itself, and the view required to bind it to the pipeline.
            D3D.BufferDescription outputBufferDescription = new D3D.BufferDescription
            {
                BindFlags           = D3D.BindFlags.UnorderedAccess | D3D.BindFlags.ShaderResource,
                OptionFlags         = D3D.ResourceOptionFlags.StructuredBuffer,
                SizeInBytes         = bufferSizeInBytes,
                StructureByteStride = sizeof(float),
                Usage = D3D.ResourceUsage.Default,
            };
            D3D.Buffer outputBuffer = new D3D.Buffer(device, outputBufferDescription);
            D3D.UnorderedAccessViewDescription outputViewDescription = new D3D.UnorderedAccessViewDescription
            {
                ElementCount = elementCount,
                Format       = DXGI.Format.Unknown,
                Dimension    = D3D.UnorderedAccessViewDimension.Buffer
            };
            D3D.UnorderedAccessView outputView = new D3D.UnorderedAccessView(device, outputBuffer, outputViewDescription);

            // Compile the shader.
            ShaderBytecode computeShaderCode = ShaderBytecode.CompileFromFile("BasicComputeShader.hlsl", "main", "cs_4_0", ShaderFlags.None, EffectFlags.None);

            D3D.ComputeShader computeShader = new D3D.ComputeShader(device, computeShaderCode);

            device.ImmediateContext.ComputeShader.Set(computeShader);
            device.ImmediateContext.ComputeShader.SetUnorderedAccessView(outputView, 0);
            device.ImmediateContext.ComputeShader.SetConstantBuffer(inputBuffer, 0);

            // Compute shaders execute on multiple threads at the same time. Those execution
            // threads are grouped; Dispatch() indicates how many groups in the X, Y and Z
            // dimension will be utilized. The shader itself specified how many threads per
            // group (also in X, Y and Z dimensions) to use via the [numthreads] attribute.
            // In this sample, one thread group will be used with 16 threads, each thread
            // will process one element of the input data.
            device.ImmediateContext.Dispatch(1, 1, 1);

            device.ImmediateContext.CopyResource(outputBuffer, stagingBuffer);
            DataBox output = device.ImmediateContext.MapSubresource(stagingBuffer, D3D.MapMode.Read, D3D.MapFlags.None);

            Console.Write("Results:");
            for (int index = 0; index < elementCount; ++index)
            {
                Console.Write(" {0}", output.Data.Read <float>());
            }
            device.ImmediateContext.UnmapSubresource(outputBuffer, 0);
            Console.WriteLine();

            computeShader.Dispose();
            outputView.Dispose();
            outputBuffer.Dispose();
            stagingBuffer.Dispose();
            inputBuffer.Dispose();
            device.Dispose();
        }