// Starts a transfer of raw data from the host to a device buffer public unsafe static void PushBuffer(byte *src, uint length, Vk.Buffer dst, uint dstOffset) { // Calculate transfer information uint blockCount = (uint)Mathf.Ceiling(length / (float)DEFAULT_BUFFER_SIZE); // Iterate over the transfer blocks for (uint bidx = 0; bidx < blockCount; ++bidx) { // Calculate offsets and block sizes uint blockOff = bidx * DEFAULT_BUFFER_SIZE; byte *currSrc = src + blockOff; uint currDstOffset = dstOffset + blockOff; uint currLength = Math.Min(length - blockOff, DEFAULT_BUFFER_SIZE); // Wait on the previous transfer s_pushFence.Wait(); s_pushFence.Reset(); // Map the staging buffer, and copy the memory IntPtr mapped = s_pushMemory.Map(0, currLength); System.Buffer.MemoryCopy(currSrc, mapped.ToPointer(), currLength, currLength); s_pushMemory.Unmap(); // Start recording s_pushCommands.Begin(ONE_TIME_SUBMIT_INFO); // Add the transfer command Vk.BufferCopy bc = new Vk.BufferCopy(currLength, 0, currDstOffset); s_pushCommands.CmdCopyBuffer(s_pushBuffer, dst, bc); // End recording, and submit s_pushCommands.End(); s_queue.Submit(s_pushSubmitInfo, fence: s_pushFence); } }
// Waits for the item fence to signal, checks if there is a valid fence to wait on public void WaitAvailable() { if (!IsSubmitted) { Waited = false; return; } Waited = Fence.GetStatus() != Vk.Result.Success; if (Waited) { Fence.Wait(); } Fence.Reset(); IsSubmitted = false; }
// Submits a one-time action that needs a graphics queue command buffer, will be synchronous // The command buffer will already have Begin() called when it is passed to the action, and will automatically call End() internal void SubmitScratchCommand(Action <Vk.CommandBuffer> action, Vk.Semaphore waitSem = null, Vk.PipelineStages waitStages = Vk.PipelineStages.AllGraphics, Vk.Fence waitFence = null) { // Record the command var cb = _scratchPool.AllocateBuffers(_scratchAllocInfo)[0]; cb.Begin(_scratchBeginInfo); action(cb); cb.End(); // Submit if (waitFence != null) { waitFence.Wait(); waitFence.Reset(); } Queues.Graphics.Submit(waitSem, waitStages, cb, null, _scratchFence); _scratchFence.Wait(); _scratchFence.Reset(); cb.Dispose(); }
/// <summary> /// Resets one or more fence objects. /// <para> /// Defines a fence unsignal operation for each fence, which resets the fence to the /// unsignaled state. /// </para> /// <para> /// If any member of <paramref name="fences"/> is already in the unsignaled state, then the /// command has no effect on that fence. /// </para> /// </summary> /// <param name="fences">Fence handles to reset.</param> /// <exception cref="VulkanException">Vulkan returns an error code.</exception> public void ResetFences(params Fence[] fences) { Fence.Reset(this, fences); }