Пример #1
0
        public void CopyBuffer_Chain_Succeeds()
        {
            DeviceBuffer src = CreateBuffer(1024, BufferUsage.Staging);

            int[] data = Enumerable.Range(0, 256).Select(i => 2 * i).ToArray();
            GD.UpdateBuffer(src, 0, data);

            DeviceBuffer finalDst = CreateBuffer(1024, BufferUsage.Staging);

            for (int chainLength = 2; chainLength <= 10; chainLength += 4)
            {
                DeviceBuffer[] dsts = Enumerable.Range(0, chainLength)
                                      .Select(i => RF.CreateBuffer(new BufferDescription(1024, BufferUsage.UniformBuffer)))
                                      .ToArray();

                CommandList copyCL = RF.CreateCommandList();
                copyCL.Begin();
                copyCL.CopyBuffer(src, 0, dsts[0], 0, src.SizeInBytes);
                for (int i = 0; i < chainLength - 1; i++)
                {
                    copyCL.CopyBuffer(dsts[i], 0, dsts[i + 1], 0, src.SizeInBytes);
                }
                copyCL.CopyBuffer(dsts[dsts.Length - 1], 0, finalDst, 0, src.SizeInBytes);
                copyCL.End();
                GD.SubmitCommands(copyCL);
                GD.WaitForIdle();

                MappedResourceView <int> view = GD.Map <int>(finalDst, MapMode.Read);
                for (int i = 0; i < view.Count; i++)
                {
                    Assert.Equal(i * 2, view[i]);
                }
                GD.Unmap(finalDst);
            }
        }
Пример #2
0
        /// <summary>
        /// Create two duplicates of a devicebuffer
        /// </summary>
        /// <param name="source">Input</param>
        /// <param name="gdev">GPU GraphicsDevice</param>
        /// <param name="dest1">Output 1</param>
        /// <param name="dest2">Output 2</param>
        /// <param name="name">buffer name prefix</param>
        public static unsafe void CreateBufferCopyPair(DeviceBuffer source, GraphicsDevice gdev, out DeviceBuffer dest1, out DeviceBuffer dest2, string name = "?")
        {
            dest1 = TrackedVRAMAlloc(gdev, source.SizeInBytes, stride: 4, name: name + "_1");
            dest2 = TrackedVRAMAlloc(gdev, source.SizeInBytes, stride: 4, name: name + "_2");

            CommandList cl = gdev.ResourceFactory.CreateCommandList();

            cl.Begin();
            cl.CopyBuffer(source, 0, dest1, 0, source.SizeInBytes);
            cl.CopyBuffer(source, 0, dest2, 0, source.SizeInBytes);
            cl.End();
            gdev.SubmitCommands(cl);
            gdev.WaitForIdle();
            cl.Dispose();
        }
Пример #3
0
        public unsafe void CopyBuffer_ZeroSize(BufferUsage usage)
        {
            DeviceBuffer src = CreateBuffer(1024, usage);
            DeviceBuffer dst = CreateBuffer(1024, usage);

            byte[] initialDataSrc = Enumerable.Range(0, 1024).Select(i => (byte)i).ToArray();
            byte[] initialDataDst = Enumerable.Range(0, 1024).Select(i => (byte)(i * 2)).ToArray();
            GD.UpdateBuffer(src, 0, initialDataSrc);
            GD.UpdateBuffer(dst, 0, initialDataDst);

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.CopyBuffer(src, 0, dst, 0, 0);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            DeviceBuffer readback = GetReadback(dst);

            MappedResourceView <byte> readMap = GD.Map <byte>(readback, MapMode.Read);

            for (int i = 0; i < 1024; i++)
            {
                Assert.Equal((byte)(i * 2), readMap[i]);
            }
            GD.Unmap(readback);
        }
Пример #4
0
        public void Copy_UnalignedRegion(
            uint srcBufferSize, BufferUsage srcUsage, uint srcCopyOffset,
            uint dstBufferSize, BufferUsage dstUsage, uint dstCopyOffset,
            uint copySize)
        {
            DeviceBuffer src = CreateBuffer(srcBufferSize, srcUsage);
            DeviceBuffer dst = CreateBuffer(dstBufferSize, dstUsage);

            byte[] data = Enumerable.Range(0, (int)srcBufferSize).Select(i => (byte)i).ToArray();
            GD.UpdateBuffer(src, 0, data);

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.CopyBuffer(src, srcCopyOffset, dst, dstCopyOffset, copySize);
            cl.End();

            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            DeviceBuffer readback = GetReadback(dst);

            MappedResourceView <byte> readView = GD.Map <byte>(readback, MapMode.Read);

            for (uint i = 0; i < copySize; i++)
            {
                byte expected = data[i + srcCopyOffset];
                byte actual   = readView[i + dstCopyOffset];
                Assert.Equal(expected, actual);
            }
            GD.Unmap(readback);
        }
Пример #5
0
        public void CopyBuffer_Succeeds()
        {
            DeviceBuffer src = CreateBuffer(1024, BufferUsage.Staging);

            int[] data = Enumerable.Range(0, 256).Select(i => 2 * i).ToArray();
            GD.UpdateBuffer(src, 0, data);

            DeviceBuffer dst = CreateBuffer(1024, BufferUsage.Staging);

            CommandList copyCL = RF.CreateCommandList();

            copyCL.Begin();
            copyCL.CopyBuffer(src, 0, dst, 0, src.SizeInBytes);
            copyCL.End();
            GD.SubmitCommands(copyCL);
            GD.WaitForIdle();
            src.Dispose();

            MappedResourceView <int> view = GD.Map <int>(dst, MapMode.Read);

            for (int i = 0; i < view.Count; i++)
            {
                Assert.Equal(i * 2, view[i]);
            }
        }
Пример #6
0
        /// <summary>
        /// Get a CPU readable mapping of VRAM
        /// </summary>
        /// <param name="gd">A veldrid graphics device</param>
        /// <param name="buffer">The buffer to read</param>
        /// <returns></returns>
        public static DeviceBuffer GetReadback(GraphicsDevice gd, DeviceBuffer?buffer)
        {
            System.Diagnostics.Debug.Assert(buffer is not null);

            DeviceBuffer readback;

            if ((buffer.Usage & BufferUsage.Staging) != 0)
            {
                readback = buffer;
            }
            else
            {
                ResourceFactory factory = gd.ResourceFactory;
                readback = TrackedVRAMAlloc(gd, buffer.SizeInBytes, BufferUsage.Staging, name: "ReadBack");
                CommandList cl = factory.CreateCommandList();
                cl.Begin();
                cl.CopyBuffer(buffer, 0, readback, 0, buffer.SizeInBytes);
                cl.End();
                gd.SubmitCommands(cl);
                gd.WaitForIdle();
                cl.Dispose();
            }

            return(readback);
        }
        private void RenderGPU()
        {
            _cl.UpdateBuffer(_sceneParamsBuffer, 0, ref _sceneParams);
            _cl.UpdateBuffer(_rayCountBuffer, 0, new Vector4());
            _cl.SetPipeline(_computePipeline);
            _cl.SetComputeResourceSet(0, _computeSet);
            Debug.Assert(Width % 16 == 0 && Height % 16 == 0);
            uint xCount = Width / 16;
            uint yCount = Height / 16;

            _cl.Dispatch(xCount, yCount, 1);
            _cl.CopyBuffer(_rayCountBuffer, 0, _rayCountReadback, 0, _rayCountBuffer.SizeInBytes);
        }
Пример #8
0
        private void RenderGpu()
        {
            commandList.UpdateBuffer(sceneParamsBuffer, 0, ref Raytracer.SceneParams);
            commandList.UpdateBuffer(rayCountBuffer, 0, new Vector4());
            commandList.SetPipeline(computePipeline);
            commandList.SetComputeResourceSet(0, computeSet);
            Debug.Assert(Window.Width % 16 == 0 && Window.Height % 16 == 0);
            var xCount = (uint)Math.Ceiling(Window.Width / 16d);
            var yCount = (uint)Math.Ceiling(Window.Height / 16d);

            commandList.Dispatch(xCount, yCount, 1);
            commandList.CopyBuffer(rayCountBuffer, 0, rayCountReadback, 0, rayCountBuffer.SizeInBytes);
            Raytracer.SceneParams.FrameCount++;
        }
Пример #9
0
        protected DeviceBuffer GetReadback(DeviceBuffer buffer)
        {
            DeviceBuffer readback;
            if ((buffer.Usage & BufferUsage.Staging) != 0)
            {
                readback = buffer;
            }
            else
            {
                readback = RF.CreateBuffer(new BufferDescription(buffer.SizeInBytes, BufferUsage.Staging));
                CommandList cl = RF.CreateCommandList();
                cl.Begin();
                cl.CopyBuffer(buffer, 0, readback, 0, buffer.SizeInBytes);
                cl.End();
                GD.SubmitCommands(cl);
                GD.WaitForIdle();
            }

            return readback;
        }
Пример #10
0
        /// <summary>
        /// Create two GPU buffer copies of a RAM buffer
        /// </summary>
        /// <param name="floats">Float array to copy</param>
        /// <param name="gdev">Veldrid graphicsdevice</param>
        /// <param name="name">Name prefix of the buffers</param>
        /// <returns>Pair of DeviceBuffers</returns>
        public static unsafe Tuple <DeviceBuffer, DeviceBuffer> CreateFloatsDeviceBufferPair(float[] floats, GraphicsDevice gdev, string name = "?")
        {
            DeviceBuffer buffer1 = TrackedVRAMAlloc(gdev, (uint)floats.Length * sizeof(float), stride: 4, name: name + "1");
            DeviceBuffer buffer2 = TrackedVRAMAlloc(gdev, (uint)floats.Length * sizeof(float), stride: 4, name: name + "2");

            fixed(float *dataPtr = floats)
            {
                CommandList cl = gdev.ResourceFactory.CreateCommandList();

                cl.Begin();
                cl.UpdateBuffer(buffer1, 0, (IntPtr)dataPtr, buffer1.SizeInBytes);
                //do we need a fence here?
                cl.CopyBuffer(buffer1, 0, buffer2, 0, buffer1.SizeInBytes);
                cl.End();
                gdev.SubmitCommands(cl);
                gdev.WaitForIdle();
                cl.Dispose();
            }

            return(new Tuple <DeviceBuffer, DeviceBuffer>(buffer1, buffer2));
        }
Пример #11
0
        public void Update_Dynamic_NonZeroOffset()
        {
            DeviceBuffer dynamic = RF.CreateBuffer(
                new BufferDescription(1024, BufferUsage.Dynamic | BufferUsage.UniformBuffer));

            byte[] initialData = Enumerable.Range(0, 1024).Select(i => (byte)i).ToArray();
            GD.UpdateBuffer(dynamic, 0, initialData);

            byte[]      replacementData = Enumerable.Repeat((byte)255, 512).ToArray();
            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.UpdateBuffer(dynamic, 512, replacementData);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            DeviceBuffer dst = RF.CreateBuffer(
                new BufferDescription(1024, BufferUsage.Staging));

            cl.Begin();
            cl.CopyBuffer(dynamic, 0, dst, 0, dynamic.SizeInBytes);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            MappedResourceView <byte> readView = GD.Map <byte>(dst, MapMode.Read);

            for (uint i = 0; i < 512; i++)
            {
                Assert.Equal((byte)i, readView[i]);
            }

            for (uint i = 512; i < 1024; i++)
            {
                Assert.Equal((byte)255, readView[i]);
            }
        }
Пример #12
0
        /*
         * public override float DistanceAt(Vector3 pos, List<int> possible)
         * {
         *  pos = Transform(pos);
         *  //unit.UpdateResources(factory, new BindableResource[] { vertexSBuffer, resultSBuffer, infoUBuffer });
         *  device.UpdateBuffer(distanceCompute.Buffer("info"), 0, pos);
         *  distanceCompute.Update(factory);
         *  commandList.Begin();
         *  distanceCompute.DispatchSized(commandList, count, 1, 1);
         *  commandList.CopyBuffer(distanceCompute.Buffer("result"), 0, distanceStaging, 0, count * sizeof(float));
         *  commandList.End();
         *  device.SubmitCommands(commandList);
         *  device.WaitForIdle();
         *
         *  var results = device.Map<float>(distanceStaging, MapMode.Read);
         *  float bestDistance = float.PositiveInfinity;
         *  int flip = 0;
         *
         *  for (int i = 0; i < count; i++) {
         *      bestDistance = Math.Min(bestDistance, Math.Abs(results[i]));
         *      if (results[i] < 0)
         *          flip++;
         *  }
         *  device.Unmap(distanceStaging);
         *
         *  if (flip % 2 == 1)
         *      bestDistance *= -1;
         *  return bestDistance / Scale;
         * }
         * private float DistanceAt(Vector3 pos)
         * {
         *  return DistanceAt(pos, new List<int>());
         * }
         * //*/
        public override bool Inside(Vector3 pos, int closest)
        {
            device.UpdateBuffer(orientationCompute.Buffer("info"), 0, pos);
            orientationCompute.Update(factory);
            commandList.Begin();
            orientationCompute.DispatchSized(commandList, count, 1, 1);
            commandList.CopyBuffer(orientationCompute.Buffer("result"), 0, orientationStaging, 0, count * sizeof(float));
            commandList.End();
            device.SubmitCommands(commandList);
            device.WaitForIdle();

            var results = device.Map <int>(orientationStaging, MapMode.Read);
            int flip    = 0;

            for (int i = 0; i < count; i++)
            {
                if (results[i] != 0)
                {
                    flip++;
                }
            }
            device.Unmap(orientationStaging);
            return(flip % 2 == 1);
        }
Пример #13
0
        public unsafe void UnusualSize()
        {
            DeviceBuffer src = RF.CreateBuffer(
                new BufferDescription(208, BufferUsage.UniformBuffer));
            DeviceBuffer dst = RF.CreateBuffer(
                new BufferDescription(208, BufferUsage.Staging));

            byte[] data = Enumerable.Range(0, 208).Select(i => (byte)(i * 150)).ToArray();
            GD.UpdateBuffer(src, 0, data);

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.CopyBuffer(src, 0, dst, 0, src.SizeInBytes);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();
            MappedResource readMap = GD.Map(dst, MapMode.Read);

            for (int i = 0; i < readMap.SizeInBytes; i++)
            {
                Assert.Equal((byte)(i * 150), ((byte *)readMap.Data)[i]);
            }
        }
Пример #14
0
        /// <summary>
        /// Executes the specified test.
        /// </summary>
        /// <param name="generationResult">The generation result.</param>
        /// <param name="csFunctionName">Name of the cs function.</param>
        /// <param name="output">The output.</param>
        public void Execute(
            ShaderGenerationResult generationResult,
            string csFunctionName,
            ITestOutputHelper output)
        {
            if (Executed)
            {
                output.WriteLine(
                    $"The {Name} tests have already been executed!");
                return;
            }

            TestSets testSets = TestSets;
            Mappings mappings = testSets.Mappings;

            if (ToolChain == null)
            {
                /*
                 * Generate the test data and the result set data for the CPU.
                 */
                AllocateResults(output);
                using (new TestTimer(output,
                                     $"Running {testSets.TestLoops} iterations on the {Name} backend"))
                {
                    for (int test = 0; test < testSets.TestLoops; test++)
                    {
                        foreach (MethodMap method in mappings.MethodMaps)
                        {
                            method.ExecuteCPU(TestSets.TestData, Results, test);
                        }
                    }

                    return;
                }
            }

            GeneratedShaderSet set;
            CompileResult      compilationResult;

            // Compile shader for this backend.
            using (new TestTimer(output, $"Compiling Compute Shader for {ToolChain.GraphicsBackend}"))
            {
                set = generationResult.GetOutput(Backend).Single();
                compilationResult =
                    ToolChain.Compile(set.ComputeShaderCode, Stage.Compute, set.ComputeFunction.Name);
            }

            if (compilationResult.HasError)
            {
                output.WriteLine($"Failed to compile Compute Shader from set \"{set.Name}\"!");
                output.WriteLine(compilationResult.ToString());
                return;
            }

            Assert.NotNull(compilationResult.CompiledOutput);

            using (GraphicsDevice graphicsDevice = ToolChain.CreateHeadless())
            {
                if (!graphicsDevice.Features.ComputeShader)
                {
                    output.WriteLine(
                        $"The {ToolChain.GraphicsBackend} backend does not support compute shaders, skipping!");
                    return;
                }

                ResourceFactory factory = graphicsDevice.ResourceFactory;
                using (DeviceBuffer inOutBuffer = factory.CreateBuffer(
                           new BufferDescription(
                               (uint)mappings.BufferSize,
                               BufferUsage.StructuredBufferReadWrite,
                               (uint)mappings.StructSize)))

                    using (Shader computeShader = factory.CreateShader(
                               new ShaderDescription(
                                   ShaderStages.Compute,
                                   compilationResult.CompiledOutput,
                                   csFunctionName)))

                        using (ResourceLayout inOutStorageLayout = factory.CreateResourceLayout(
                                   new ResourceLayoutDescription(
                                       new ResourceLayoutElementDescription("InOutBuffer", ResourceKind.StructuredBufferReadWrite,
                                                                            ShaderStages.Compute))))

                            using (Pipeline computePipeline = factory.CreateComputePipeline(new ComputePipelineDescription(
                                                                                                computeShader,
                                                                                                new[] { inOutStorageLayout },
                                                                                                1, 1, 1)))


                                using (ResourceSet computeResourceSet = factory.CreateResourceSet(
                                           new ResourceSetDescription(inOutStorageLayout, inOutBuffer)))

                                    using (CommandList commandList = factory.CreateCommandList())
                                    {
                                        // Ensure the headless graphics device is the backend we expect.
                                        Assert.Equal(ToolChain.GraphicsBackend, graphicsDevice.BackendType);

                                        output.WriteLine($"Created compute pipeline for {Name} backend.");

                                        // Allocate the results buffer
                                        AllocateResults(output);

                                        using (new TestTimer(output,
                                                             $"Running {testSets.TestLoops} iterations on the {Name} backend"))
                                        {
                                            // Loop for each test
                                            for (int test = 0; test < testSets.TestLoops; test++)
                                            {
                                                // Update parameter buffer
                                                graphicsDevice.UpdateBuffer(
                                                    inOutBuffer,
                                                    0,
                                                    // Get the portion of test data for the current test loop
                                                    Marshal.UnsafeAddrOfPinnedArrayElement(testSets.TestData, mappings.BufferSize * test),
                                                    (uint)mappings.BufferSize);
                                                graphicsDevice.WaitForIdle();

                                                // Execute compute shaders
                                                commandList.Begin();
                                                commandList.SetPipeline(computePipeline);
                                                commandList.SetComputeResourceSet(0, computeResourceSet);
                                                commandList.Dispatch((uint)mappings.Methods, 1, 1);
                                                commandList.End();

                                                graphicsDevice.SubmitCommands(commandList);
                                                graphicsDevice.WaitForIdle();

                                                // Read back parameters using a staging buffer
                                                using (DeviceBuffer stagingBuffer =
                                                           factory.CreateBuffer(
                                                               new BufferDescription(inOutBuffer.SizeInBytes, BufferUsage.Staging)))
                                                {
                                                    commandList.Begin();
                                                    commandList.CopyBuffer(inOutBuffer, 0, stagingBuffer, 0, stagingBuffer.SizeInBytes);
                                                    commandList.End();
                                                    graphicsDevice.SubmitCommands(commandList);
                                                    graphicsDevice.WaitForIdle();

                                                    // Read back test results
                                                    MappedResource map = graphicsDevice.Map(stagingBuffer, MapMode.Read);

                                                    mappings.SetResults(map.Data, Results, test);
                                                    graphicsDevice.Unmap(stagingBuffer);
                                                }
                                            }
                                        }
                                    }
            }
        }
Пример #15
0
 public void Process(CommandList context)
 {
     context.CopyBuffer(OutputBufferIndex, InputBufferIndex);
 }
 public void FillBuffer <T>(GraphicsDevice d, CommandList cl, ref T data) where T : struct
 {
     //cl.UpdateBuffer(_allocator._backingBuffer, AllocationStart, ref data);
     d.UpdateBuffer(_allocator._stagingBuffer, AllocationStart, data);
     cl.CopyBuffer(_allocator._stagingBuffer, AllocationStart, _allocator._backingBuffer, AllocationStart, AllocationSize);
 }