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); } }
/// <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(); }
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); }
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); }
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]); } }
/// <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); }
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++; }
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; }
/// <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)); }
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]); } }
/* * 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); }
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]); } }
/// <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); } } } } } }
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); }