/// <summary> /// Create a new index buffer with data initialized from a <see cref="HostBuffer"/>. /// </summary> /// <param name="indexCount">The number of indicies in the buffer.</param> /// <param name="type">The index type.</param> /// <param name="indexData">The initial index data, which must be large enough to supply the buffer.</param> /// <param name="dataOffset">The offset into the data source buffer from which to copy.</param> /// <param name="usage">The buffer usage policy.</param> public IndexBuffer(uint indexCount, IndexType type, HostBuffer indexData, ulong dataOffset = 0, BufferUsage usage = BufferUsage.Dynamic) : base(indexCount * (uint)type, ResourceType.IndexBuffer, usage, indexData, dataOffset) { IndexCount = indexCount; IndexType = type; }
/// <summary> /// Create a new vertex buffer with the data in the host buffer. /// </summary> /// <param name="vertexCount">The number of vertices in the buffer.</param> /// <param name="description">The layout of the vertices in the buffer.</param> /// <param name="data">The optional initial vertex data.</param> /// <param name="dataOffset">The offset into the data source buffer from which to copy.</param> /// <param name="usage">The buffer usage policy.</param> public VertexBuffer(uint vertexCount, VertexDescription description, HostBuffer data, ulong dataOffset = 0, BufferUsage usage = BufferUsage.Static) : base(vertexCount * description.Stride, ResourceType.VertexBuffer, usage, data, dataOffset) { VertexCount = vertexCount; VertexDescription = description.Duplicate(); }
// Sets the buffer data by copying from a prepared host buffer // Pass null as bufferType to signal a first-time copy that does not need pipeline barriers public void SetBufferData(ResourceType?bufferType, ulong dataSize, HostBuffer srcBuffer, ulong srcOffset, VkBuffer dstBuffer, ulong dstOffset ) { // Record the copy command RecordBufferCopy(_cmd, bufferType, dataSize, srcBuffer.Buffer, srcOffset, dstBuffer, dstOffset); // Submit and wait Graphics.GraphicsQueue.SubmitRaw(_cmd, _fence); var waitHandle = _fence.Handle; Graphics.VkDevice.WaitForFences(1, &waitHandle, VkBool32.True, UInt64.MaxValue); // Reset pool _pool.ResetCommandPool(VkCommandPoolResetFlags.ReleaseResources); Graphics.VkDevice.ResetFences(1, &waitHandle); }
// Update the data (non-static buffers only) from an existing host buffer protected void SetDataImpl(HostBuffer data, ulong size, ulong srcOffset, ulong dstOffset) { // Validate ThrowIfDisposed(); if (Usage == BufferUsage.Static) { throw new InvalidOperationException("Cannot update data for static-usage buffers"); } if ((size + dstOffset) > DataSize) { throw new InvalidOperationException("Cannot update data outside of buffer range"); } if ((size + srcOffset) > data.DataSize) { throw new InvalidOperationException("Cannot update from data outside of host buffer range"); } if (size == 0) { throw new InvalidOperationException("Cannot update buffer from data of length 0"); } // Check dynamic frame if (Usage == BufferUsage.Dynamic) { if (AppTime.FrameCount == _lastDynamicUpdate) { throw new InvalidOperationException("Dynamic buffers can only be updated once per frame"); } _lastDynamicUpdate = AppTime.FrameCount; } // Perform async update Graphics.Resources.TransferManager.UpdateBufferAsync( ResourceType, size, data.Buffer, srcOffset, Handle, dstOffset ); }
/// <summary> /// Create a filled texture with the given dimensions and format. /// </summary> /// <param name="width">The width of the texture.</param> /// <param name="height">The height of the texture.</param> /// <param name="format">The texel format.</param> /// <param name="data">The initial texture data. Must be large enough to fill entire texture.</param> /// <param name="dataOff">The offset into the buffered data to upload.</param> /// <param name="usage">The texture usage policy.</param> public Texture2D(uint width, uint height, TexelFormat format, HostBuffer data, ulong dataOff = 0, TextureUsage usage = TextureUsage.Static) : base(width, height, 1, 1, 1, format, usage, ResourceType.Texture2D) { SetDataImpl(data, dataOff, new(0, 0, 0, width, height, 1, 0, 1)); }
/// <summary> /// Updates the vertex buffer data with data from the passed host buffer. Only allowed on non-Static buffers. /// </summary> /// <param name="data">The host buffer to update from.</param> /// <param name="vertexCount">The number of vertices to update.</param> /// <param name="srcOffset">The offset into <paramref name="data"/>, in bytes, from which to copy.</param> /// <param name="dstVertexOffset">The offset into the buffer, in vertices, to which to copy.</param> public void SetData(HostBuffer data, uint vertexCount, uint srcOffset, uint dstVertexOffset) => SetDataImpl(data, vertexCount * Stride, srcOffset, dstVertexOffset * Stride);
/// <summary> /// Updates the index buffer data with data from the passed host buffer. Only valid on non-Static buffers. /// </summary> /// <param name="data">The data buffer from which to copy.</param> /// <param name="indexCount">The number of indices to update.</param> /// <param name="srcOffset">The offset into the source buffer, in bytes.</param> /// <param name="indexOffset">The offset into the buffer, in indices, to which to copy.</param> public void SetData(HostBuffer data, uint indexCount, uint srcOffset, uint indexOffset) { var indexSize = (IndexType == IndexType.Short) ? 2u : 4u; SetDataImpl(data, indexCount * indexSize, srcOffset, indexOffset * indexSize); }
private protected DeviceBuffer(ulong size, ResourceType type, BufferUsage usage, HostBuffer initialData, ulong dataOffset) : base(type) { // Validate data if (size == 0) { throw new ArgumentOutOfRangeException(nameof(size), "Buffer size cannot be zero"); } if (size > initialData.DataSize) { throw new InvalidOperationException("Host buffer is not large enough to supply device buffer data"); } // Set fields DataSize = size; Usage = usage; CreateBuffer(size, type, out Handle, out Memory); // Set initial data Graphics.Resources.TransferManager.SetBufferData(null, DataSize, initialData, dataOffset, Handle, 0); }
// Sets the texture data by copying from a prepared host buffer // Pass null as imageType to signal a first-time copy that does not need pipeline barriers public void SetImageData(ResourceType imageType, TexelFormat format, bool discard, HostBuffer srcBuffer, ulong srcOffset, VkImage dstImage, in TextureRegion dstRegion)