public void BindIndexBuffer(Vk api, CommandBufferScoped cbs) { if (_buffer != null) { api.CmdBindIndexBuffer(cbs.CommandBuffer, _buffer.Get(cbs, _offset, _size).Value, (ulong)_offset, _type); } }
private void PushDataImpl(CommandBufferScoped cbs, BufferHolder dst, int dstOffset, ReadOnlySpan <byte> data) { var srcBuffer = _buffer.GetBuffer(); var dstBuffer = dst.GetBuffer(); int offset = _freeOffset; int capacity = BufferSize - offset; if (capacity < data.Length) { _buffer.SetDataUnchecked(offset, data.Slice(0, capacity)); _buffer.SetDataUnchecked(0, data.Slice(capacity)); BufferHolder.Copy(_gd, cbs, srcBuffer, dstBuffer, offset, dstOffset, capacity); BufferHolder.Copy(_gd, cbs, srcBuffer, dstBuffer, 0, dstOffset + capacity, data.Length - capacity); } else { _buffer.SetDataUnchecked(offset, data); BufferHolder.Copy(_gd, cbs, srcBuffer, dstBuffer, offset, dstOffset, data.Length); } _freeOffset = (offset + data.Length) & (BufferSize - 1); _freeSize -= data.Length; Debug.Assert(_freeSize >= 0); _pendingCopies.Enqueue(new PendingCopy(cbs.GetFence(), data.Length)); }
private DescriptorSetCollection CreateBuffer(CommandBufferScoped cbs, ref BufferHandleSet key, int setIndex, DescriptorType type) { var dsc = _gd.DescriptorSetManager.AllocateDescriptorSet(_gd.Api, _descriptorSetLayouts[setIndex]).Get(cbs); Span <DescriptorBufferInfo> bufferInfos = stackalloc DescriptorBufferInfo[key.Count]; for (int i = 0; i < key.Count; i++) { uint size = key.Sizes[i]; if (type == DescriptorType.UniformBufferDynamic) { size = Math.Min(size, 0x10000); } bufferInfos[i] = new DescriptorBufferInfo() { Buffer = new VkBuffer(key.Handles[i]), Offset = 0, Range = size }; } dsc.UpdateBuffers(0, 0, bufferInfos, type); return(dsc); }
public void SetDataInline(CommandBufferScoped cbs, Action endRenderPass, int dstOffset, ReadOnlySpan <byte> data) { if (!TryPushData(cbs, endRenderPass, dstOffset, data)) { throw new ArgumentException($"Invalid offset 0x{dstOffset:X} or data size 0x{data.Length:X}."); } }
public void AddCommandBufferDependencies(CommandBufferScoped cbs) { // We don't want to add a reference to this object to the command buffer // more than once, so if we detect that the command buffer already has ownership // of this object, then we can just return without doing anything else. if (_cbOwnership.Set(cbs.CommandBufferIndex)) { if (_waitable != null) { cbs.AddWaitable(_waitable); } cbs.AddDependant(this); // We need to add a dependency on the command buffer to all objects this object // references aswell. if (_referencedObjs != null) { for (int i = 0; i < _referencedObjs.Length; i++) { _referencedObjs[i].AddCommandBufferDependencies(cbs); } } } }
public void BindTransformFeedbackBuffer(VulkanRenderer gd, CommandBufferScoped cbs, uint binding) { if (_buffer != null) { var buffer = _buffer.Get(cbs, _offset, _size).Value; gd.TransformFeedbackApi.CmdBindTransformFeedbackBuffers(cbs.CommandBuffer, binding, 1, buffer, (ulong)_offset, (ulong)_size); } }
public Auto <DisposableBuffer> GetBufferI8ToI16(CommandBufferScoped cbs, BufferHandle handle, int offset, int size) { if (TryGetBuffer(handle, out var holder)) { return(holder.GetBufferI8ToI16(cbs, offset, size)); } return(null); }
public void BindVertexBuffer(VulkanGraphicsDevice gd, CommandBufferScoped cbs, uint binding) { if (_buffer != null) { var buffer = _buffer.Get(cbs, _offset, _size).Value; gd.Api.CmdBindVertexBuffers(cbs.CommandBuffer, binding, 1, buffer, (ulong)_offset); } }
public T Get(CommandBufferScoped cbs) { if (!_destroyed) { AddCommandBufferDependencies(cbs); } return(_value); }
public BufferView GetBufferView(CommandBufferScoped cbs) { if (_bufferView == null) { _bufferView = _gd.BufferManager.CreateView(_bufferHandle, VkFormat, _offset, _size); } return _bufferView?.Get(cbs, _offset, _size).Value ?? default; }
private static void UpdateBuffer(CommandBufferScoped cbs, ref DescriptorBufferInfo info, Auto <DisposableBuffer> buffer) { info.Buffer = buffer?.Get(cbs, (int)info.Offset, (int)info.Range).Value ?? default; // The spec requires that buffers with null handle have offset as 0 and range as VK_WHOLE_SIZE. if (info.Buffer.Handle == 0) { info.Offset = 0; info.Range = Vk.WholeSize; } }
public Auto <DisposableBuffer> GetBufferI8ToI16(CommandBufferScoped cbs, int offset, int size) { if (!_cachedConvertedIndexBuffers.TryGetValue(offset, size, out var holder)) { holder = _gd.BufferManager.Create(_gd, (size * 2 + 3) & ~3); _gd.HelperShader.ConvertI8ToI16(_gd, cbs, this, holder, offset, size); _cachedConvertedIndexBuffers.Add(offset, size, holder); } return(holder.GetBuffer()); }
public void SetCommandBuffer(CommandBufferScoped cbs) { CommandBuffer = (Cbs = cbs).CommandBuffer; // Restore per-command buffer state. if (Pipeline != null) { Gd.Api.CmdBindPipeline(CommandBuffer, Pbp, Pipeline.Get(CurrentCommandBuffer).Value); } SignalCommandBufferChange(); }
private unsafe bool TryPushData(CommandBufferScoped cbs, Action endRenderPass, int dstOffset, ReadOnlySpan <byte> data) { if ((dstOffset & 3) != 0 || (data.Length & 3) != 0) { return(false); } endRenderPass(); var dstBuffer = GetBuffer(cbs.CommandBuffer, true).Get(cbs, dstOffset, data.Length).Value; InsertBufferBarrier( _gd, cbs.CommandBuffer, dstBuffer, BufferHolder.DefaultAccessFlags, AccessFlags.AccessTransferWriteBit, PipelineStageFlags.PipelineStageAllCommandsBit, PipelineStageFlags.PipelineStageTransferBit, dstOffset, data.Length); fixed(byte *pData = data) { for (ulong offset = 0; offset < (ulong)data.Length;) { ulong size = Math.Min(MaxUpdateBufferSize, (ulong)data.Length - offset); _gd.Api.CmdUpdateBuffer(cbs.CommandBuffer, dstBuffer, (ulong)dstOffset + offset, size, pData + offset); offset += size; } } InsertBufferBarrier( _gd, cbs.CommandBuffer, dstBuffer, AccessFlags.AccessTransferWriteBit, BufferHolder.DefaultAccessFlags, PipelineStageFlags.PipelineStageTransferBit, PipelineStageFlags.PipelineStageAllCommandsBit, dstOffset, data.Length); // Not flushing commands here causes glitches on Intel (driver bug?) if (_gd.IsIntelGpu) { _gd.FlushAllCommands(); } return(true); }
private static DescriptorSetCollection GetOrCreate <T>( CommandBufferScoped cbs, ref T key, Dictionary <T, DescriptorSetCollection> hashTable, CreateCallback <T> createCallback) { if (!hashTable.TryGetValue(key, out var ds)) { ds = createCallback(cbs, ref key); hashTable.Add(key, ds); } return(ds); }
private DescriptorSetCollection CreateBufferImage(CommandBufferScoped cbs, ref HandleSet key, int setIndex, DescriptorType type) { var dsc = _gd.DescriptorSetManager.AllocateDescriptorSet(_gd.Api, _descriptorSetLayouts[setIndex]).Get(cbs); Span <BufferView> texelBufferView = stackalloc BufferView[key.Count]; for (int i = 0; i < key.Count; i++) { texelBufferView[i] = new BufferView(key.Handles[i]); } dsc.UpdateBufferImages(0, 0, texelBufferView, type); return(dsc); }
public unsafe bool TryPushData(CommandBufferScoped cbs, Action endRenderPass, BufferHolder dst, int dstOffset, ReadOnlySpan <byte> data) { if (data.Length > BufferSize) { return(false); } if (_freeSize < data.Length) { FreeCompleted(); if (_freeSize < data.Length) { return(false); } } endRenderPass(); var srcBuffer = _buffer.GetBuffer(); var dstBuffer = dst.GetBuffer(); int offset = _freeOffset; int capacity = BufferSize - offset; if (capacity < data.Length) { _buffer.SetDataUnchecked(offset, data.Slice(0, capacity)); _buffer.SetDataUnchecked(0, data.Slice(capacity)); BufferHolder.Copy(_gd, cbs, srcBuffer, dstBuffer, offset, dstOffset, capacity); BufferHolder.Copy(_gd, cbs, srcBuffer, dstBuffer, 0, dstOffset + capacity, data.Length - capacity); } else { _buffer.SetDataUnchecked(offset, data); BufferHolder.Copy(_gd, cbs, srcBuffer, dstBuffer, offset, dstOffset, data.Length); } _freeOffset = (offset + data.Length) & (BufferSize - 1); _freeSize -= data.Length; Debug.Assert(_freeSize >= 0); _pendingCopies.Enqueue(new PendingCopy(cbs.GetFence(), data.Length)); return(true); }
public unsafe void PushData(CommandBufferPool cbp, CommandBufferScoped?cbs, Action endRenderPass, BufferHolder dst, int dstOffset, ReadOnlySpan <byte> data) { bool isRender = cbs != null; CommandBufferScoped scoped = cbs ?? cbp.Rent(); // Must push all data to the buffer. If it can't fit, split it up. endRenderPass?.Invoke(); while (data.Length > 0) { if (_freeSize < data.Length) { FreeCompleted(); } while (_freeSize == 0) { if (!WaitFreeCompleted(cbp)) { if (isRender) { _gd.FlushAllCommands(); scoped = cbp.Rent(); isRender = false; } else { scoped = cbp.ReturnAndRent(scoped); } } } int chunkSize = Math.Min(_freeSize, data.Length); PushDataImpl(scoped, dst, dstOffset, data.Slice(0, chunkSize)); dstOffset += chunkSize; data = data.Slice(chunkSize); } if (!isRender) { scoped.Dispose(); } }
private DescriptorSetCollection CreateImage(CommandBufferScoped cbs, ref HandleSet key) { var dsc = _gd.DescriptorSetManager.AllocateDescriptorSet(_gd.Api, _descriptorSetLayouts[PipelineBase.ImageSetIndex]).Get(cbs); Span <DescriptorImageInfo> imageInfos = stackalloc DescriptorImageInfo[key.Count]; for (int i = 0; i < key.Count; i++) { imageInfos[i] = new DescriptorImageInfo() { ImageLayout = ImageLayout.General, ImageView = new ImageView(key.Handles[i]) }; } dsc.UpdateImages(0, 0, imageInfos, DescriptorType.StorageImage); return(dsc); }
public unsafe void ConvertI8ToI16(VulkanRenderer gd, CommandBufferScoped cbs, BufferHolder src, BufferHolder dst, int srcOffset, int size) { // TODO: Do this with a compute shader? var srcBuffer = src.GetBuffer().Get(cbs, srcOffset, size).Value; var dstBuffer = dst.GetBuffer().Get(cbs, 0, size * 2).Value; gd.Api.CmdFillBuffer(cbs.CommandBuffer, dstBuffer, 0, Vk.WholeSize, 0); var bufferCopy = new BufferCopy[size]; for (ulong i = 0; i < (ulong)size; i++) { bufferCopy[i] = new BufferCopy((ulong)srcOffset + i, i * 2, 1); } BufferHolder.InsertBufferBarrier( gd, cbs.CommandBuffer, dstBuffer, BufferHolder.DefaultAccessFlags, AccessFlags.AccessTransferWriteBit, PipelineStageFlags.PipelineStageAllCommandsBit, PipelineStageFlags.PipelineStageTransferBit, 0, size * 2); fixed(BufferCopy *pBufferCopy = bufferCopy) { gd.Api.CmdCopyBuffer(cbs.CommandBuffer, srcBuffer, dstBuffer, (uint)size, pBufferCopy); } BufferHolder.InsertBufferBarrier( gd, cbs.CommandBuffer, dstBuffer, AccessFlags.AccessTransferWriteBit, BufferHolder.DefaultAccessFlags, PipelineStageFlags.PipelineStageTransferBit, PipelineStageFlags.PipelineStageAllCommandsBit, 0, size * 2); }
public void UpdateAndBindDescriptorSets(CommandBufferScoped cbs, PipelineBindPoint pbp) { if ((_dirty & DirtyFlags.All) == 0) { return; } // System.Console.WriteLine("modified " + _dirty + " " + _modified + " on program " + _program.GetHashCode().ToString("X")); if (_dirty.HasFlag(DirtyFlags.Uniform)) { UpdateAndBind(cbs, PipelineBase.UniformSetIndex, DirtyFlags.Uniform, pbp); } if (_dirty.HasFlag(DirtyFlags.Storage)) { UpdateAndBind(cbs, PipelineBase.StorageSetIndex, DirtyFlags.Storage, pbp); } if (_dirty.HasFlag(DirtyFlags.Texture)) { UpdateAndBind(cbs, PipelineBase.TextureSetIndex, DirtyFlags.Texture, pbp); } if (_dirty.HasFlag(DirtyFlags.Image)) { UpdateAndBind(cbs, PipelineBase.ImageSetIndex, DirtyFlags.Image, pbp); } if (_dirty.HasFlag(DirtyFlags.BufferTexture)) { UpdateAndBind(cbs, PipelineBase.BufferTextureSetIndex, DirtyFlags.BufferTexture, pbp); } if (_dirty.HasFlag(DirtyFlags.BufferImage)) { UpdateAndBind(cbs, PipelineBase.BufferImageSetIndex, DirtyFlags.BufferImage, pbp); } _dirty = DirtyFlags.None; }
public BufferView GetBufferView(CommandBufferScoped cbs, GAL.Format format) { var vkFormat = FormatTable.GetFormat(format); if (vkFormat == VkFormat) { return GetBufferView(cbs); } if (_selfManagedViews != null && _selfManagedViews.TryGetValue(format, out var bufferView)) { return bufferView.Get(cbs, _offset, _size).Value; } bufferView = _gd.BufferManager.CreateView(_bufferHandle, vkFormat, _offset, _size); if (bufferView != null) { (_selfManagedViews ??= new Dictionary<GAL.Format, Auto<DisposableBufferView>>()).Add(format, bufferView); } return bufferView?.Get(cbs, _offset, _size).Value ?? default; }
public static unsafe void Copy( VulkanRenderer gd, CommandBufferScoped cbs, Auto <DisposableBuffer> src, Auto <DisposableBuffer> dst, int srcOffset, int dstOffset, int size) { var srcBuffer = src.Get(cbs, srcOffset, size).Value; var dstBuffer = dst.Get(cbs, dstOffset, size).Value; InsertBufferBarrier( gd, cbs.CommandBuffer, dstBuffer, BufferHolder.DefaultAccessFlags, AccessFlags.AccessTransferWriteBit, PipelineStageFlags.PipelineStageAllCommandsBit, PipelineStageFlags.PipelineStageTransferBit, dstOffset, size); var region = new BufferCopy((ulong)srcOffset, (ulong)dstOffset, (ulong)size); gd.Api.CmdCopyBuffer(cbs.CommandBuffer, srcBuffer, dstBuffer, 1, ®ion); InsertBufferBarrier( gd, cbs.CommandBuffer, dstBuffer, AccessFlags.AccessTransferWriteBit, BufferHolder.DefaultAccessFlags, PipelineStageFlags.PipelineStageTransferBit, PipelineStageFlags.PipelineStageAllCommandsBit, dstOffset, size); }
public void BindVertexBuffer(VulkanRenderer gd, CommandBufferScoped cbs, uint binding) { if (_buffer != null) { var buffer = _buffer.Get(cbs, _offset, _size).Value; if (gd.Capabilities.SupportsExtendedDynamicState) { gd.ExtendedDynamicStateApi.CmdBindVertexBuffers2( cbs.CommandBuffer, binding, 1, buffer, (ulong)_offset, (ulong)_size, _stride); } else { gd.Api.CmdBindVertexBuffers(cbs.CommandBuffer, binding, 1, buffer, (ulong)_offset); } } }
public unsafe bool TryPushData(CommandBufferScoped cbs, Action endRenderPass, BufferHolder dst, int dstOffset, ReadOnlySpan <byte> data) { if (data.Length > BufferSize) { return(false); } if (_freeSize < data.Length) { FreeCompleted(); if (_freeSize < data.Length) { return(false); } } endRenderPass(); PushDataImpl(cbs, dst, dstOffset, data); return(true); }
public unsafe Auto <DisposableFramebuffer> Create(Vk api, CommandBufferScoped cbs, Auto <DisposableRenderPass> renderPass) { ImageView *attachments = stackalloc ImageView[_attachments.Length]; for (int i = 0; i < _attachments.Length; i++) { attachments[i] = _attachments[i].Get(cbs).Value; } var framebufferCreateInfo = new FramebufferCreateInfo() { SType = StructureType.FramebufferCreateInfo, RenderPass = renderPass.Get(cbs).Value, AttachmentCount = (uint)_attachments.Length, PAttachments = attachments, Width = Width, Height = Height, Layers = Layers }; api.CreateFramebuffer(_device, framebufferCreateInfo, null, out var framebuffer).ThrowOnError(); return(new Auto <DisposableFramebuffer>(new DisposableFramebuffer(api, _device, framebuffer), null, _attachments)); }
public DescriptorSetCollection GetTexture(CommandBufferScoped cbs, ref CombinedImageHandleSet key) { return(GetOrCreate(cbs, ref key, _tCache, CreateImage)); }
private DescriptorSetCollection CreateStorageBuffer(CommandBufferScoped cbs, ref BufferHandleSet key) { return(CreateBuffer(cbs, ref key, PipelineBase.StorageSetIndex, DescriptorType.StorageBufferDynamic)); }
public DescriptorSetCollection GetBufferImage(CommandBufferScoped cbs, ref HandleSet key) { return(GetOrCreate(cbs, ref key, _bICache, CreateBufferImage)); }
private DescriptorSetCollection CreateBufferImage(CommandBufferScoped cbs, ref HandleSet key) { return(CreateBufferImage(cbs, ref key, PipelineBase.BufferImageSetIndex, DescriptorType.StorageTexelBuffer)); }