public unsafe void MapWrite_ThenMapRead_1D() { if (!GD.Features.Texture1D) { return; } Texture tex1D = RF.CreateTexture( TextureDescription.Texture1D(100, 1, 1, PixelFormat.R16_UNorm, TextureUsage.Staging)); MappedResourceView <ushort> writeView = GD.Map <ushort>(tex1D, MapMode.Write); Assert.Equal(tex1D.Width, (uint)writeView.Count); for (int i = 0; i < writeView.Count; i++) { writeView[i] = (ushort)(i * 2); } GD.Unmap(tex1D); MappedResourceView <ushort> view = GD.Map <ushort>(tex1D, MapMode.Read); for (int i = 0; i < view.Count; i++) { Assert.Equal((ushort)(i * 2), view[i]); } GD.Unmap(tex1D); }
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]); } }
public unsafe void MapWrite_ThenMapRead_3D() { Texture tex3D = RF.CreateTexture(TextureDescription.Texture3D( 10, 10, 10, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging)); MappedResourceView <RgbaByte> writeView = GD.Map <RgbaByte>(tex3D, MapMode.Write); for (int z = 0; z < tex3D.Depth; z++) { for (int y = 0; y < tex3D.Height; y++) { for (int x = 0; x < tex3D.Width; x++) { writeView[x, y, z] = new RgbaByte((byte)x, (byte)y, (byte)z, 1); } } } GD.Unmap(tex3D); MappedResourceView <RgbaByte> readView = GD.Map <RgbaByte>(tex3D, MapMode.Read, 0); for (int z = 0; z < tex3D.Depth; z++) { for (int y = 0; y < tex3D.Height; y++) { for (int x = 0; x < tex3D.Width; x++) { Assert.Equal(new RgbaByte((byte)x, (byte)y, (byte)z, 1), readView[x, y, z]); } } } GD.Unmap(tex3D); }
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_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); } }
public void Map_ThenRead_MultipleArrayLayers() { Texture src = RF.CreateTexture(TextureDescription.Texture2D( 10, 10, 1, 10, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging)); for (uint layer = 0; layer < src.ArrayLayers; layer++) { MappedResourceView <RgbaByte> writeView = GD.Map <RgbaByte>(src, MapMode.Write, layer); for (int y = 0; y < src.Height; y++) { for (int x = 0; x < src.Width; x++) { writeView[x, y] = new RgbaByte((byte)x, (byte)y, (byte)layer, 1); } } GD.Unmap(src, layer); } for (uint layer = 0; layer < src.ArrayLayers; layer++) { MappedResourceView <RgbaByte> readView = GD.Map <RgbaByte>(src, MapMode.Read, layer); for (int y = 0; y < src.Height; y++) { for (int x = 0; x < src.Width; x++) { Assert.Equal(new RgbaByte((byte)x, (byte)y, (byte)layer, 1), readView[x, y]); } } GD.Unmap(src, layer); } }
public unsafe void Update_WithOffset_2D() { Texture tex2D = RF.CreateTexture(TextureDescription.Texture2D( 100, 100, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging)); RgbaByte[] data = new RgbaByte[50 * 30]; for (uint y = 0; y < 30; y++) { for (uint x = 0; x < 50; x++) { data[y * 50 + x] = new RgbaByte((byte)x, (byte)y, 0, 1); } fixed(RgbaByte *dataPtr = &data[0]) { GD.UpdateTexture( tex2D, (IntPtr)dataPtr, (uint)(data.Length * sizeof(RgbaByte)), 50, 70, 0, 50, 30, 1, 0, 0); } MappedResourceView <RgbaByte> readView = GD.Map <RgbaByte>(tex2D, MapMode.Read); for (int y = 0; y < 30; y++) { for (int x = 0; x < 50; x++) { Assert.Equal(new RgbaByte((byte)x, (byte)y, 0, 1), readView[x + 50, y + 70]); } } }
public void NoDepthTarget_ClearAllColors_Succeeds() { Texture colorTarget = RF.CreateTexture( TextureDescription.Texture2D(1024, 1024, 1, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.RenderTarget)); Framebuffer fb = RF.CreateFramebuffer(new FramebufferDescription(null, colorTarget)); CommandList cl = RF.CreateCommandList(); cl.Begin(); cl.SetFramebuffer(fb); cl.ClearColorTarget(0, RgbaFloat.Red); cl.End(); GD.SubmitCommands(cl); GD.WaitForIdle(); Texture staging = RF.CreateTexture( TextureDescription.Texture2D(1024, 1024, 1, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.Staging)); cl.Begin(); cl.CopyTexture( colorTarget, 0, 0, 0, 0, 0, staging, 0, 0, 0, 0, 0, 1024, 1024, 1, 1); cl.End(); GD.SubmitCommands(cl); GD.WaitForIdle(); MappedResourceView <RgbaFloat> view = GD.Map <RgbaFloat>(staging, MapMode.Read); for (int i = 0; i < view.Count; i++) { Assert.Equal(RgbaFloat.Red, view[i]); } GD.Unmap(staging); }
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 unsafe void Map_NonZeroMip_3D() { Texture tex3D = RF.CreateTexture(TextureDescription.Texture3D( 40, 40, 40, 3, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging)); MappedResourceView <RgbaByte> writeView = GD.Map <RgbaByte>(tex3D, MapMode.Write, 2); for (int z = 0; z < 10; z++) { for (int y = 0; y < 10; y++) { for (int x = 0; x < 10; x++) { writeView[x, y, z] = new RgbaByte((byte)x, (byte)y, (byte)z, 1); } } } GD.Unmap(tex3D, 2); MappedResourceView <RgbaByte> readView = GD.Map <RgbaByte>(tex3D, MapMode.Read, 2); for (int z = 0; z < 10; z++) { for (int y = 0; y < 10; y++) { for (int x = 0; x < 10; x++) { Assert.Equal(new RgbaByte((byte)x, (byte)y, (byte)z, 1), readView[x, y, z]); } } } GD.Unmap(tex3D, 2); }
public void Update_MultipleMips_1D() { if (!GD.Features.Texture1D) { return; } Texture tex1D = RF.CreateTexture(TextureDescription.Texture1D( 100, 5, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging)); for (uint level = 0; level < tex1D.MipLevels; level++) { MappedResourceView <RgbaByte> writeView = GD.Map <RgbaByte>(tex1D, MapMode.Write, level); for (int i = 0; i < writeView.Count; i++) { writeView[i] = new RgbaByte((byte)i, (byte)(i * 2), (byte)level, 1); } GD.Unmap(tex1D, level); } for (uint level = 0; level < tex1D.MipLevels; level++) { MappedResourceView <RgbaByte> readView = GD.Map <RgbaByte>(tex1D, MapMode.Read, level); for (int i = 0; i < readView.Count; i++) { Assert.Equal(new RgbaByte((byte)i, (byte)(i * 2), (byte)level, 1), readView[i]); } GD.Unmap(tex1D, level); } }
public void MapGeneric_OutOfBounds_ThrowsIndexOutOfRange() { DeviceBuffer buffer = CreateBuffer(1024, BufferUsage.Staging); MappedResourceView <byte> view = GD.Map <byte>(buffer, MapMode.ReadWrite); Assert.Throws <IndexOutOfRangeException>(() => view[1024]); Assert.Throws <IndexOutOfRangeException>(() => view[-1]); }
public static unsafe Span <T> AsSpan <T>(this MappedResourceView <T> resource, uint start) where T : unmanaged { if (start >= (uint)resource.Count) { throw new ArgumentOutOfRangeException(nameof(start)); } return(new Span <T>((T *)resource.MappedResource.Data + start, resource.Count - (int)start)); }
public static unsafe Bitmap CreateRecordingFrame(Framebuffer fbuf, float startX, float startY, float drawWidth, float drawHeight) { GraphicsDevice gd = _controller !.GraphicsDevice; Texture ftex = fbuf.ColorTargets[0].Target; if (_recordingStager == null || _recordingStager.Width != ftex.Width || _recordingStager.Height != ftex.Height) { VeldridGraphBuffers.DoDispose(_recordingStager); _recordingStager = gd.ResourceFactory.CreateTexture(new TextureDescription(ftex.Width, ftex.Height, 1, 1, 1, PixelFormat.B8_G8_R8_A8_UNorm, TextureUsage.Staging, TextureType.Texture2D)); } _commandList !.Begin(); _commandList.CopyTexture(ftex, _recordingStager); _commandList.End(); gd.SubmitCommands(_commandList); gd.WaitForIdle(); if (drawWidth == -1 || drawHeight == -1) { drawHeight = _recordingStager.Height; drawWidth = _recordingStager.Width; } //draw it onto a bitmap Bitmap bmp = new Bitmap((int)drawWidth, (int)drawHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb); System.Drawing.Imaging.BitmapData data = bmp.LockBits(new System.Drawing.Rectangle(0, 0, (int)drawWidth, (int)drawHeight), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); byte *scan0 = (byte *)data.Scan0; MappedResourceView <SixLabors.ImageSharp.PixelFormats.Rgba32> res = gd.Map <SixLabors.ImageSharp.PixelFormats.Rgba32>(_recordingStager, MapMode.Read); for (int y = 0; y < drawHeight; y += 1) { for (int x = 0; x < drawWidth; x += 1) { int xPixel = (int)startX + x; int yPixel = (int)startY + y; SixLabors.ImageSharp.PixelFormats.Rgba32 px = res[xPixel, yPixel]; byte *ptr = scan0 + y * data.Stride + (x * 4); ptr[0] = px.R; ptr[1] = px.G; ptr[2] = px.B; ptr[3] = 255; } } bmp.UnlockBits(data); gd.Unmap(_recordingStager); return(bmp); }
/// <summary> /// Returns the number of texels in the texture that DO NOT match the fill value. /// </summary> private static int CountTexelsNotFilledAtDepth <TexelType>(GraphicsDevice device, Texture texture, TexelType fillValue, uint depth) where TexelType : unmanaged { ResourceFactory factory = device.ResourceFactory; // We need to create a staging texture and copy into it. TextureDescription description = new TextureDescription(texture.Width, texture.Height, depth: 1, texture.MipLevels, texture.ArrayLayers, texture.Format, TextureUsage.Staging, texture.Type, texture.SampleCount); Texture staging = factory.CreateTexture(ref description); using CommandList cl = factory.CreateCommandList(); cl.Begin(); cl.CopyTexture(texture, srcX: 0, srcY: 0, srcZ: depth, srcMipLevel: 0, srcBaseArrayLayer: 0, staging, dstX: 0, dstY: 0, dstZ: 0, dstMipLevel: 0, dstBaseArrayLayer: 0, staging.Width, staging.Height, depth: 1, layerCount: 1); cl.End(); device.SubmitCommands(cl); device.WaitForIdle(); try { MappedResourceView <TexelType> mapped = device.Map <TexelType>(staging, MapMode.Read); int notFilledCount = 0; for (int y = 0; y < staging.Height; y++) { for (int x = 0; x < staging.Width; x++) { TexelType actual = mapped[x, y]; if (!fillValue.Equals(actual)) { notFilledCount++; } } } return(notFilledCount); } finally { device.Unmap(staging); } }
public void NonZeroMipLevel_ClearColor_Succeeds() { Texture testTex = RF.CreateTexture( TextureDescription.Texture2D(1024, 1024, 11, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.RenderTarget)); Framebuffer[] framebuffers = new Framebuffer[11]; for (uint level = 0; level < 11; level++) { framebuffers[level] = RF.CreateFramebuffer( new FramebufferDescription(null, new[] { new FramebufferAttachmentDescription(testTex, 0, level) })); } CommandList cl = RF.CreateCommandList(); cl.Begin(); for (uint level = 0; level < 11; level++) { cl.SetFramebuffer(framebuffers[level]); cl.ClearColorTarget(0, new RgbaFloat(level, level, level, 1)); } cl.End(); GD.SubmitCommands(cl); GD.WaitForIdle(); Texture readback = RF.CreateTexture( TextureDescription.Texture2D(1024, 1024, 11, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.Staging)); cl.Begin(); cl.CopyTexture(testTex, readback); cl.End(); GD.SubmitCommands(cl); GD.WaitForIdle(); uint mipWidth = 1024; uint mipHeight = 1024; for (uint level = 0; level < 11; level++) { MappedResourceView <RgbaFloat> readView = GD.Map <RgbaFloat>(readback, MapMode.Read, level); for (uint y = 0; y < mipHeight; y++) { for (uint x = 0; x < mipWidth; x++) { Assert.Equal(new RgbaFloat(level, level, level, 1), readView[x, y]); } } GD.Unmap(readback, level); mipWidth = Math.Max(1, mipWidth / 2); mipHeight = Math.Max(1, mipHeight / 2); } }
public void MapThenUpdate_Fails() { if (GD.BackendType == GraphicsBackend.Vulkan) { return; // TODO } Buffer buffer = RF.CreateBuffer(new BufferDescription(1024, BufferUsage.Staging)); MappedResourceView <int> view = GD.Map <int>(buffer, MapMode.ReadWrite); int[] data = Enumerable.Range(0, 256).Select(i => 2 * i).ToArray(); Assert.Throws <VeldridException>(() => GD.UpdateBuffer(buffer, 0, data)); }
public unsafe void Copy_Compressed_Texture(PixelFormat format, uint blockSizeInBytes, uint srcX, uint srcY, uint copyWidth, uint copyHeight) { if (!GD.GetPixelFormatSupport(format, TextureType.Texture2D, TextureUsage.Sampled)) { return; } Texture copySrc = RF.CreateTexture(TextureDescription.Texture2D( 64, 64, 1, 1, format, TextureUsage.Staging)); Texture copyDst = RF.CreateTexture(TextureDescription.Texture2D( copyWidth, copyHeight, 1, 1, format, TextureUsage.Staging)); const int numPixelsInBlockSide = 4; const int numPixelsInBlock = 16; uint totalDataSize = copyWidth * copyHeight / numPixelsInBlock * blockSizeInBytes; byte[] data = new byte[totalDataSize]; for (int i = 0; i < data.Length; i++) { data[i] = (byte)i; } fixed(byte *dataPtr = data) { GD.UpdateTexture(copySrc, (IntPtr)dataPtr, totalDataSize, srcX, srcY, 0, copyWidth, copyHeight, 1, 0, 0); } CommandList cl = RF.CreateCommandList(); cl.Begin(); cl.CopyTexture( copySrc, srcX, srcY, 0, 0, 0, copyDst, 0, 0, 0, 0, 0, copyWidth, copyHeight, 1, 1); cl.End(); GD.SubmitCommands(cl); GD.WaitForIdle(); uint numBytesPerRow = copyWidth / numPixelsInBlockSide * blockSizeInBytes; MappedResourceView <byte> view = GD.Map <byte>(copyDst, MapMode.Read); for (uint i = 0; i < data.Length; i++) { uint viewRow = i / numBytesPerRow; uint viewIndex = (view.MappedResource.RowPitch * viewRow) + (i % numBytesPerRow); Assert.Equal(data[i], view[viewIndex]); } GD.Unmap(copyDst); }
public void UpdateBuffer_ThenMapRead_Succeeds() { DeviceBuffer buffer = CreateBuffer(1024, BufferUsage.Staging); int[] data = Enumerable.Range(0, 256).Select(i => 2 * i).ToArray(); GD.UpdateBuffer(buffer, 0, data); MappedResourceView <int> view = GD.Map <int>(buffer, MapMode.Read); for (int i = 0; i < view.Count; i++) { Assert.Equal(i * 2, view[i]); } }
public unsafe void Update_NonStaging_3D() { Texture tex3D = RF.CreateTexture(TextureDescription.Texture3D( 16, 16, 16, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Sampled)); RgbaByte[] data = new RgbaByte[16 * 16 * 16]; for (int z = 0; z < 16; z++) for (int y = 0; y < 16; y++) { for (int x = 0; x < 16; x++) { int index = (int)(z * tex3D.Width * tex3D.Height + y * tex3D.Height + x); data[index] = new RgbaByte((byte)x, (byte)y, (byte)z, 1); } } fixed(RgbaByte *dataPtr = data) { GD.UpdateTexture(tex3D, (IntPtr)dataPtr, (uint)(data.Length * Unsafe.SizeOf <RgbaByte>()), 0, 0, 0, tex3D.Width, tex3D.Height, tex3D.Depth, 0, 0); } Texture staging = RF.CreateTexture(TextureDescription.Texture3D( 16, 16, 16, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging)); CommandList cl = RF.CreateCommandList(); cl.Begin(); cl.CopyTexture(tex3D, staging); cl.End(); GD.SubmitCommands(cl); GD.WaitForIdle(); MappedResourceView <RgbaByte> view = GD.Map <RgbaByte>(staging, MapMode.Read); for (int z = 0; z < tex3D.Depth; z++) for (int y = 0; y < tex3D.Height; y++) { for (int x = 0; x < tex3D.Width; x++) { Assert.Equal(new RgbaByte((byte)x, (byte)y, (byte)z, 1), view[x, y, z]); } } }
public void UpdateUniform_Offset_GraphicsDevice(BufferUsage usage) { DeviceBuffer buffer = CreateBuffer(128, usage); Matrix4x4 mat1 = new Matrix4x4(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); GD.UpdateBuffer(buffer, 0, ref mat1); Matrix4x4 mat2 = new Matrix4x4(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2); GD.UpdateBuffer(buffer, 64, ref mat2); DeviceBuffer readback = GetReadback(buffer); MappedResourceView <Matrix4x4> readView = GD.Map <Matrix4x4>(readback, MapMode.Read); Assert.Equal(mat1, readView[0]); Assert.Equal(mat2, readView[1]); GD.Unmap(readback); }
public void Copy_WithOffsets_2D(TextureUsage srcUsage, TextureUsage dstUsage) { Texture src = RF.CreateTexture(TextureDescription.Texture2D( 100, 100, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, srcUsage)); Texture dst = RF.CreateTexture(TextureDescription.Texture2D( 100, 100, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, dstUsage)); RgbaByte[] srcData = new RgbaByte[src.Height * src.Width]; for (int y = 0; y < src.Height; y++) { for (int x = 0; x < src.Width; x++) { srcData[y * src.Width + x] = new RgbaByte((byte)x, (byte)y, 0, 1); } } GD.UpdateTexture(src, srcData, 0, 0, 0, src.Width, src.Height, 1, 0, 0); CommandList cl = RF.CreateCommandList(); cl.Begin(); cl.CopyTexture( src, 50, 50, 0, 0, 0, dst, 10, 10, 0, 0, 0, 50, 50, 1, 1); cl.End(); GD.SubmitCommands(cl); GD.WaitForIdle(); Texture readback = GetReadback(dst); MappedResourceView <RgbaByte> readView = GD.Map <RgbaByte>(readback, MapMode.Read); for (int y = 10; y < 60; y++) { for (int x = 10; x < 60; x++) { Assert.Equal(new RgbaByte((byte)(x + 40), (byte)(y + 40), 0, 1), readView[x, y]); } } GD.Unmap(readback); }
/// <summary> /// Called when everything is added to the queue once per frame /// </summary> public void RenderQueue() { GraphicsDevice gd = PerlinApp.DefaultGraphicsDevice; float width = gd.MainSwapchain.Framebuffer.Width; float height = gd.MainSwapchain.Framebuffer.Height; gd.UpdateBuffer( PerlinApp.Pipeline.OrthoBuffer, 0, Matrix4x4.CreateOrthographicOffCenter(0, width, height, 0, 0, 1)); EnsureVertexBufferSize((uint)_renderQueue.Count * QuadVertex.VertexSize); MappedResourceView <QuadVertex> writeMap = gd.Map <QuadVertex>(_vertexBuffer, MapMode.Write); for (int i = 0; i < _renderQueue.Count; i++) { writeMap[i] = _renderQueue[i].GpuVertex; } gd.Unmap(_vertexBuffer); var cl = PerlinApp.CommandList; cl.SetPipeline(PerlinApp.Pipeline.Pipeline); cl.SetVertexBuffer(0, _vertexBuffer); cl.SetGraphicsResourceSet(0, PerlinApp.Pipeline.OrthoSet); DrawCount = 0; for (int i = 0; i < _renderQueue.Count;) { uint batchStart = (uint)i; ResourceSet rs = _renderQueue[i].ResSet; cl.SetGraphicsResourceSet(1, rs); // textField needs here an extra UpdateBuffer call? cl.UpdateBuffer(_textBuffer, 0, toDraw[0].GpuVertex); // Render objects that use the same ResourceSet and come after each other in one draw call uint batchSize = 0; do { i += 1; batchSize += 1; }while (i < _renderQueue.Count && _renderQueue[i].ResSet == rs); DrawCount++; cl.Draw(4, batchSize, 0, batchStart); } _renderQueue.Clear(); }
public void Staging_MapGeneric_WriteThenRead() { Buffer buffer = CreateBuffer(1024, BufferUsage.Staging); MappedResourceView <int> view = GD.Map <int>(buffer, MapMode.Write); Assert.Equal(256, view.Count); for (int i = 0; i < view.Count; i++) { view[i] = i * 10; } GD.Unmap(buffer); view = GD.Map <int>(buffer, MapMode.Read); Assert.Equal(256, view.Count); for (int i = 0; i < view.Count; i++) { view[i] = 1 * 10; } }
public unsafe void Update_ThenMapRead_1D() { Texture tex1D = RF.CreateTexture( TextureDescription.Texture1D(100, 1, 1, PixelFormat.R16_UNorm, TextureUsage.Staging)); ushort[] data = Enumerable.Range(0, (int)tex1D.Width).Select(i => (ushort)(i * 2)).ToArray(); fixed(ushort *dataPtr = &data[0]) { GD.UpdateTexture(tex1D, (IntPtr)dataPtr, (uint)(data.Length * sizeof(ushort)), 0, 0, 0, tex1D.Width, 1, 1, 0, 0); } MappedResourceView <ushort> view = GD.Map <ushort>(tex1D, MapMode.Read); for (int i = 0; i < view.Count; i++) { Assert.Equal((ushort)(i * 2), view[i]); } GD.Unmap(tex1D); }
/// <summary> /// Read out some values from a DeviceBuffer and print them to the console. Just for debugging. /// </summary> /// <param name="buf">GPU DeviceBuffer to read</param> /// <param name="message">Caption for the printout</param> /// <param name="printCount">Max values to print</param> private void DebugPrintOutputFloatBuffer(DeviceBuffer buf, string message, int printCount) { DeviceBuffer destinationReadback = VeldridGraphBuffers.GetReadback(_gd !, buf); MappedResourceView <float> destinationReadView = _gd !.Map <float>(destinationReadback, MapMode.Read); float[] outputArray = new float[destinationReadView.Count]; for (int index = 0; index < destinationReadView.Count; index++) { if (index >= destinationReadView.Count) { break; } outputArray[index] = destinationReadView[index]; } _gd.Unmap(destinationReadback); PrintFloatBufferArray(outputArray, message, printCount); VeldridGraphBuffers.VRAMDispose(destinationReadback); }
private void RenderFrame() { _sceneParams.FrameCount += 1; _cl.Begin(); if (_drawModeCPU) { RenderCPU(); } else { RenderGPU(); } fixed(RgbaFloat *pixelDataPtr = _fb) { _gd.UpdateTexture(_transferTex, (IntPtr)pixelDataPtr, Width * Height * (uint)sizeof(RgbaFloat), 0, 0, 0, Width, Height, 1, 0, 0); } _cl.SetFramebuffer(_gd.MainSwapchain.Framebuffer); _cl.SetPipeline(_graphicsPipeline); _cl.SetGraphicsResourceSet(0, _graphicsSet); _cl.Draw(3); _cl.End(); _gd.SubmitCommands(_cl); _gd.SwapBuffers(); if (!_drawModeCPU) { MappedResourceView <uint> rayCountView = _gd.Map <uint>(_rayCountReadback, MapMode.Read); _totalRays += rayCountView[0]; _gd.Unmap(_rayCountReadback); } float seconds = _stopwatch.ElapsedMilliseconds / 1000f; float rate = _totalRays / seconds; float mRate = rate / 1_000_000; float frameRate = _sceneParams.FrameCount / (float)_stopwatch.Elapsed.TotalSeconds; _window.Title = $"Elapsed: {seconds} sec. | Rate: {mRate} MRays / sec. | {frameRate} fps"; }
public void Copy_WitOffsets_2D() { Texture src = RF.CreateTexture(TextureDescription.Texture2D( 100, 100, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging)); Texture dst = RF.CreateTexture(TextureDescription.Texture2D( 100, 100, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Staging)); MappedResourceView <RgbaByte> writeView = GD.Map <RgbaByte>(src, MapMode.Write); for (int y = 0; y < src.Height; y++) { for (int x = 0; x < src.Width; x++) { writeView[x, y] = new RgbaByte((byte)x, (byte)y, 0, 1); } } GD.Unmap(src); CommandList cl = RF.CreateCommandList(); cl.Begin(); cl.CopyTexture( src, 50, 50, 0, 0, 0, dst, 10, 10, 0, 0, 0, 50, 50, 1, 1); cl.End(); GD.SubmitCommands(cl); GD.WaitForIdle(); MappedResourceView <RgbaByte> readView = GD.Map <RgbaByte>(dst, MapMode.Read); for (int y = 10; y < 60; y++) { for (int x = 10; x < 60; x++) { Assert.Equal(new RgbaByte((byte)(x + 40), (byte)(y + 40), 0, 1), readView[x, y]); } } GD.Unmap(dst); }
public void Copy_DifferentMip_1DTo2D() { if (!GD.Features.Texture1D) { return; } Texture tex1D = RF.CreateTexture( TextureDescription.Texture1D(200, 2, 1, PixelFormat.R16_UNorm, TextureUsage.Staging)); Texture tex2D = RF.CreateTexture( TextureDescription.Texture2D(100, 10, 1, 1, PixelFormat.R16_UNorm, TextureUsage.Staging)); MappedResourceView <ushort> writeView = GD.Map <ushort>(tex1D, MapMode.Write, 1); Assert.Equal(tex2D.Width, (uint)writeView.Count); for (int i = 0; i < writeView.Count; i++) { writeView[i] = (ushort)(i * 2); } GD.Unmap(tex1D, 1); CommandList cl = RF.CreateCommandList(); cl.Begin(); cl.CopyTexture( tex1D, 0, 0, 0, 1, 0, tex2D, 0, 5, 0, 0, 0, tex2D.Width, 1, 1, 1); cl.End(); GD.SubmitCommands(cl); GD.DisposeWhenIdle(cl); GD.WaitForIdle(); MappedResourceView <ushort> readView = GD.Map <ushort>(tex2D, MapMode.Read); for (int i = 0; i < tex2D.Width; i++) { Assert.Equal((ushort)(i * 2), readView[i, 5]); } GD.Unmap(tex2D); }
public unsafe void UpdateBuffer_ZeroSize(BufferUsage usage, bool useCommandListUpdate) { DeviceBuffer buffer = CreateBuffer(1024, usage); byte[] initialData = Enumerable.Range(0, 1024).Select(i => (byte)i).ToArray(); byte[] otherData = Enumerable.Range(0, 1024).Select(i => (byte)(i + 10)).ToArray(); GD.UpdateBuffer(buffer, 0, initialData); if (useCommandListUpdate) { CommandList cl = RF.CreateCommandList(); cl.Begin(); fixed(byte *dataPtr = otherData) { cl.UpdateBuffer(buffer, 0, (IntPtr)dataPtr, 0); } cl.End(); GD.SubmitCommands(cl); GD.WaitForIdle(); } else { fixed(byte *dataPtr = otherData) { GD.UpdateBuffer(buffer, 0, (IntPtr)dataPtr, 0); } } DeviceBuffer readback = GetReadback(buffer); MappedResourceView <byte> readMap = GD.Map <byte>(readback, MapMode.Read); for (int i = 0; i < 1024; i++) { Assert.Equal((byte)i, readMap[i]); } GD.Unmap(readback); }