Esempio n. 1
0
        /// <summary>
        /// Invalidate a range of mapped memory.
        /// <para>
        /// Must be used to guarantee that device writes to non-coherent memory are visible to the
        /// host. It must be called after command buffers that execute and flush (via memory
        /// barriers) the device writes have completed, and before the host will read or write any of
        /// those locations. If a range of non-coherent memory is written by the host and then
        /// invalidated without first being flushed, its contents are undefined.
        /// </para>
        /// <para>
        /// Mapping non-coherent memory does not implicitly invalidate the mapped memory, and device
        /// writes that have not been invalidated must be made visible before the host reads or
        /// overwrites them.
        /// </para>
        /// </summary>
        /// <param name="memoryRange">Structure describing the memory range to invalidate.</param>
        /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
        public void InvalidateMappedMemoryRange(MappedMemoryRange memoryRange)
        {
            memoryRange.Prepare();
            Result result = vkInvalidateMappedMemoryRanges(this, 1, &memoryRange);

            VulkanException.ThrowForInvalidResult(result);
        }
Esempio n. 2
0
        /// <summary>
        /// Wait for the fence to become signaled.
        /// <para>
        /// If the condition is satisfied when the command is called, then the command returns
        /// immediately. If the condition is not satisfied at the time the command is called, then
        /// the command will block and wait up to timeout nanoseconds for the condition to become satisfied.
        /// </para>
        /// </summary>
        /// <param name="timeout">
        /// The timeout period in units of nanoseconds. Timeout is adjusted to the closest value
        /// allowed by the implementation-dependent timeout accuracy, which may be substantially
        /// longer than one nanosecond, and may be longer than the requested period.
        /// <para>
        /// If timeout is zero, then the command does not wait, but simply returns the current state
        /// of the fences. The result <see cref="Result.Timeout"/> will be thrown in this case if the
        /// condition is not satisfied, even though no actual wait was performed.
        /// </para>
        /// <para>
        /// If the specified timeout period expires before the condition is satisfied, the command
        /// throws with <see cref="Result.Timeout"/>. If the condition is satisfied before timeout
        /// nanoseconds has expired, the command returns successfully.
        /// </para>
        /// </param>
        /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
        public void Wait(long timeout = ~0)
        {
            long   handle = this;
            Result result = vkWaitForFences(Parent, 1, &handle, false, timeout);

            VulkanException.ThrowForInvalidResult(result);
        }
        /// <summary>
        /// Submits semaphores or a command buffer to a queue.
        /// </summary>
        /// <param name="fence">
        /// An optional handle to a fence to be signaled. If fence is not <c>null</c>, it defines a
        /// fence signal operation.
        /// </param>
        /// <param name="waitSemaphore">
        /// Semaphore upon which to wait before the command buffer for this batch begins execution.
        /// If semaphore to wait on is provided, it defines a semaphore wait operation.
        /// </param>
        /// <param name="waitDstStageMask">Pipeline stages at which semaphore wait will occur.</param>
        /// <param name="commandBuffer">Command buffer to execute in the batch.</param>
        /// <param name="signalSemaphore">
        /// Semaphore which will be signaled when the command buffer for this batch has completed
        /// execution. If semaphore to be signaled is provided, it defines a semaphore signal operation.
        /// </param>
        /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
        public void Submit(Semaphore waitSemaphore, PipelineStages waitDstStageMask,
                           CommandBuffer commandBuffer, Semaphore signalSemaphore, Fence fence = null)
        {
            long   waitSemaphoreHandle   = waitSemaphore;
            IntPtr commandBufferHandle   = commandBuffer;
            long   signalSemaphoreHandle = signalSemaphore;

            var nativeSubmit = new SubmitInfo.Native {
                Type = StructureType.SubmitInfo
            };

            if (waitSemaphoreHandle != 0)
            {
                nativeSubmit.WaitSemaphoreCount = 1;
                nativeSubmit.WaitSemaphores     = new IntPtr(&waitSemaphoreHandle);
                nativeSubmit.WaitDstStageMask   = new IntPtr(&waitDstStageMask);
            }
            if (commandBufferHandle != IntPtr.Zero)
            {
                nativeSubmit.CommandBufferCount = 1;
                nativeSubmit.CommandBuffers     = new IntPtr(&commandBufferHandle);
            }
            if (signalSemaphoreHandle != 0)
            {
                nativeSubmit.SignalSemaphoreCount = 1;
                nativeSubmit.SignalSemaphores     = new IntPtr(&signalSemaphoreHandle);
            }

            Result result = vkQueueSubmit(this, 1, &nativeSubmit, fence);

            VulkanException.ThrowForInvalidResult(result);
        }
Esempio n. 4
0
        /// <summary>
        /// Resets the fence object.
        /// <para>Defines a fence unsignal operation, which resets the fence to the unsignaled state.</para>
        /// <para>
        /// If fence is already in the unsignaled state, then the command has no effect on that fence.
        /// </para>
        /// </summary>
        /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
        public void Reset()
        {
            long   handle = this;
            Result result = vkResetFences(Parent, 1, &handle);

            VulkanException.ThrowForInvalidResult(result);
        }
Esempio n. 5
0
        /// <summary>
        /// Returns global extension properties.
        /// </summary>
        /// <param name="layerName">
        /// Is either <c>null</c> or a unicode string naming the layer to retrieve extensions from.
        /// When parameter is <c>null</c>, only extensions provided by the Vulkan implementation or
        /// by implicitly enabled layers are returned.
        /// </param>
        /// <returns>Properties of available extensions for layer.</returns>
        /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
        public static ExtensionProperties[] EnumerateExtensionProperties(string layerName = null)
        {
            int dstLayerNameByteCount = Interop.String.GetMaxByteCount(layerName);
            var dstLayerNamePtr       = stackalloc byte[dstLayerNameByteCount];

            Interop.String.ToPointer(layerName, dstLayerNamePtr, dstLayerNameByteCount);

            int    count;
            Result result = vkEnumerateInstanceExtensionProperties(dstLayerNamePtr, &count, null);

            VulkanException.ThrowForInvalidResult(result);

            var propertiesPtr = stackalloc ExtensionProperties.Native[count];

            result = vkEnumerateInstanceExtensionProperties(dstLayerNamePtr, &count, propertiesPtr);
            VulkanException.ThrowForInvalidResult(result);

            var properties = new ExtensionProperties[count];

            for (int i = 0; i < count; i++)
            {
                ExtensionProperties.FromNative(ref propertiesPtr[i], out properties[i]);
            }
            return(properties);
        }
Esempio n. 6
0
        /// <summary>
        /// Combine the data stores of pipeline caches.
        /// </summary>
        /// <param name="sourceCache">Pipeline cache to merge into this.</param>
        public void MergeCache(PipelineCache sourceCache)
        {
            long   handle = sourceCache;
            Result result = vkMergePipelineCaches(Parent, this, 1, &handle);

            VulkanException.ThrowForInvalidResult(result);
        }
        /// <summary>
        /// Submits a sequence of semaphores or command buffers to a queue.
        /// </summary>
        /// <param name="submit">Specifies a command buffer submission batch.</param>
        /// <param name="fence">
        /// An optional handle to a fence to be signaled. If fence is not <c>null</c>, it defines a
        /// fence signal operation.
        /// </param>
        /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
        public void Submit(SubmitInfo submit, Fence fence = null)
        {
            submit.ToNative(out SubmitInfo.Native nativeSubmit);
            Result result = vkQueueSubmit(this, 1, &nativeSubmit, fence);

            nativeSubmit.Free();
            VulkanException.ThrowForInvalidResult(result);
        }
        /// <summary>
        /// Bind device memory to a sparse resource object.
        /// </summary>
        /// <param name="bindInfo">Specifying a sparse binding submission batch.</param>
        /// <param name="fence">
        /// An optional handle to a fence to be signaled. If fence is not <c>null</c>, it defines a
        /// fence signal operation.
        /// </param>
        /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
        public void BindSparse(BindSparseInfo bindInfo, Fence fence = null)
        {
            bindInfo.ToNative(out BindSparseInfo.Native nativeBindInfo);
            Result result = vkQueueBindSparse(this, 1, &nativeBindInfo, fence);

            nativeBindInfo.Free();
            VulkanException.ThrowForInvalidResult(result);
        }
Esempio n. 9
0
        /// <summary>
        /// Map a memory object into application address space.
        /// <para>
        /// It is an application error to call <see cref="Map"/> on a memory object that is already mapped.
        /// </para>
        /// <para>
        /// Will fail if the implementation is unable to allocate an appropriately sized contiguous
        /// virtual address range, e.g. due to virtual address space fragmentation or platform
        /// limits. In such cases, <see cref="Map"/> must return <see
        /// cref="Result.ErrorMemoryMapFailed"/>. The application can improve the likelihood of
        /// success by reducing the size of the mapped range and/or removing unneeded mappings using
        /// <see cref="Unmap"/>.
        /// </para>
        /// <para>
        /// Does not check whether the device memory is currently in use before returning the
        /// host-accessible pointer. The application must guarantee that any previously submitted
        /// command that writes to this range has completed before the host reads from or writes to
        /// that range, and that any previously submitted command that reads from that range has
        /// completed before the host writes to that region (see here for details on fulfilling such
        /// a guarantee). If the device memory was allocated without the <see
        /// cref="MemoryProperties.HostCoherent"/> set, these guarantees must be made for an extended
        /// range: the application must round down the start of the range to the nearest multiple of
        ///        <see cref="PhysicalDeviceLimits.NonCoherentAtomSize"/>, and round the end of the
        /// range up to the nearest multiple of <see cref="PhysicalDeviceLimits.NonCoherentAtomSize"/>.
        /// </para>
        /// <para>
        /// While a range of device memory is mapped for host access, the application is responsible
        /// for synchronizing both device and host access to that memory range.
        /// </para>
        /// </summary>
        /// <param name="offset">A zero-based byte offset from the beginning of the memory object.</param>
        /// <param name="size">
        /// The size of the memory range to map, or <see cref="Constant.WholeSize"/> to map from
        /// offset to the end of the allocation.
        /// </param>
        /// <returns>
        /// A pointer in which is returned a host-accessible pointer to the beginning of the mapped
        /// range. This pointer minus offset must be aligned to at least <see cref="PhysicalDeviceLimits.MinMemoryMapAlignment"/>.
        /// </returns>
        /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
        public IntPtr Map(long offset, long size)
        {
            IntPtr ptr;
            Result result = vkMapMemory(Parent, this, offset, size, 0, &ptr);

            VulkanException.ThrowForInvalidResult(result);
            return(ptr);
        }
Esempio n. 10
0
        /// <summary>
        /// Retrieve the status of an event object. Upon success, the command returns the state of
        /// the event object with the following return codes:
        /// <para>* <see cref="Result.EventSet"/> - The event is signaled</para>
        /// <para>* <see cref="Result.EventReset"/> - The event is unsignaled</para>
        /// </summary>
        /// <returns><see cref="Result.EventSet"/> if the event is signaled; otherwise <see cref="Result.EventReset"/>.</returns>
        /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
        public Result GetStatus()
        {
            Result result = vkGetEventStatus(Parent, this);

            if (result != Result.EventSet && result != Result.EventReset)
            {
                VulkanException.ThrowForInvalidResult(result);
            }
            return(result);
        }
Esempio n. 11
0
        /// <summary>
        /// Return the status of a fence. Upon success, returns the status of the fence object, with
        /// the following return codes:
        /// <para>* <see cref="Result.Success"/> - The fence is signaled</para>
        /// <para>* <see cref="Result.NotReady"/> - The fence is unsignaled</para>
        /// </summary>
        /// <returns><see cref="Result.Success"/> if the fence is signaled; otherwise <see cref="Result.NotReady"/>.</returns>
        /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
        public Result GetStatus()
        {
            Result result = vkGetFenceStatus(Parent, this);

            if (result != Result.Success && result != Result.NotReady)
            {
                VulkanException.ThrowForInvalidResult(result);
            }
            return(result);
        }
Esempio n. 12
0
 /// <summary>
 /// Free descriptor set.
 /// </summary>
 /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
 public override void Dispose()
 {
     if (!Disposed)
     {
         long   handle = this;
         Result result = vkFreeDescriptorSets(Parent.Parent, Parent, 1, &handle);
         VulkanException.ThrowForInvalidResult(result);
     }
     base.Dispose();
 }
Esempio n. 13
0
        internal CommandPool(Device parent, CommandPoolCreateInfo *createInfo, ref AllocationCallbacks?allocator)
        {
            Parent    = parent;
            Allocator = allocator;

            createInfo->Prepare();
            long   handle;
            Result result = vkCreateCommandPool(Parent, createInfo, NativeAllocator, &handle);

            VulkanException.ThrowForInvalidResult(result);
            Handle = handle;
        }
Esempio n. 14
0
        /// <summary>
        /// Invalidate ranges of mapped memory objects.
        /// <para>
        /// Must be used to guarantee that device writes to non-coherent memory are visible to the
        /// host. It must be called after command buffers that execute and flush (via memory
        /// barriers) the device writes have completed, and before the host will read or write any of
        /// those locations. If a range of non-coherent memory is written by the host and then
        /// invalidated without first being flushed, its contents are undefined.
        /// </para>
        /// <para>
        /// Mapping non-coherent memory does not implicitly invalidate the mapped memory, and device
        /// writes that have not been invalidated must be made visible before the host reads or
        /// overwrites them.
        /// </para>
        /// </summary>
        /// <param name="memoryRanges">Structures describing the memory ranges to invalidate.</param>
        /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
        public void InvalidateMappedMemoryRanges(params MappedMemoryRange[] memoryRanges)
        {
            int count = memoryRanges?.Length ?? 0;

            for (int i = 0; i < count; i++)
                memoryRanges[i].Prepare();

            fixed (MappedMemoryRange* memoryRangesPtr = memoryRanges)
            {
                Result result = vkInvalidateMappedMemoryRanges(this, count, memoryRangesPtr);
                VulkanException.ThrowForInvalidResult(result);
            }
        }
Esempio n. 15
0
        internal Device(PhysicalDevice parent, ref DeviceCreateInfo createInfo, ref AllocationCallbacks? allocator)
        {
            Parent = parent;
            Allocator = allocator;

            createInfo.ToNative(out DeviceCreateInfo.Native nativeCreateInfo);
            IntPtr handle;
            Result result = vkCreateDevice(Parent.Handle, &nativeCreateInfo, NativeAllocator, &handle);
            nativeCreateInfo.Free();

            VulkanException.ThrowForInvalidResult(result);
            Handle = handle;
        }
Esempio n. 16
0
        internal ImageView(Device parent, Image image, ImageViewCreateInfo *createInfo, ref AllocationCallbacks?allocator)
        {
            Parent    = parent;
            Allocator = allocator;

            createInfo->Prepare(image);

            long   handle;
            Result result = vkCreateImageView(Parent, createInfo, NativeAllocator, &handle);

            VulkanException.ThrowForInvalidResult(result);
            Handle = handle;
        }
Esempio n. 17
0
        internal static void Wait(Device parent, Fence[] fences, bool waitAll, long timeout)
        {
            int   count   = fences?.Length ?? 0;
            long *handles = stackalloc long[count];

            for (int i = 0; i < count; i++)
            {
                handles[i] = fences[i];
            }
            Result result = vkWaitForFences(parent, count, handles, waitAll, timeout);

            VulkanException.ThrowForInvalidResult(result);
        }
Esempio n. 18
0
        internal DeviceMemory(Device parent, MemoryAllocateInfo *allocateInfo, ref AllocationCallbacks?allocator)
        {
            Parent    = parent;
            Allocator = allocator;

            long handle;

            allocateInfo->Prepare();
            Result result = vkAllocateMemory(parent, allocateInfo, NativeAllocator, &handle);

            VulkanException.ThrowForInvalidResult(result);
            Handle = handle;
        }
Esempio n. 19
0
        internal static void Reset(Device parent, Fence[] fences)
        {
            int   count   = fences?.Length ?? 0;
            long *handles = stackalloc long[count];

            for (int i = 0; i < count; i++)
            {
                handles[i] = fences[i];
            }
            Result result = vkResetFences(parent, count, handles);

            VulkanException.ThrowForInvalidResult(result);
        }
Esempio n. 20
0
        internal static void Free(DescriptorPool parent, DescriptorSet[] descriptorSets)
        {
            int count             = descriptorSets?.Length ?? 0;
            var descriptorSetsPtr = stackalloc long[count];

            for (int i = 0; i < count; i++)
            {
                descriptorSetsPtr[i] = descriptorSets[i];
            }

            Result result = vkFreeDescriptorSets(parent.Parent, parent, count, descriptorSetsPtr);

            VulkanException.ThrowForInvalidResult(result);
        }
Esempio n. 21
0
        internal Semaphore(Device parent, ref AllocationCallbacks?allocator)
        {
            Parent    = parent;
            Allocator = allocator;

            var createInfo = new SemaphoreCreateInfo();

            createInfo.Prepare();

            long   handle;
            Result result = vkCreateSemaphore(Parent, &createInfo, NativeAllocator, &handle);

            VulkanException.ThrowForInvalidResult(result);
            Handle = handle;
        }
Esempio n. 22
0
        /// <summary>
        /// Combine the data stores of pipeline caches.
        /// </summary>
        /// <param name="sourceCaches">Pipeline caches to merge into this.</param>
        public void MergeCaches(params PipelineCache[] sourceCaches)
        {
            int count = sourceCaches?.Length ?? 0;

            var sourceCachesPtr = stackalloc long[count];

            for (int i = 0; i < count; i++)
            {
                sourceCachesPtr[i] = sourceCaches[i].Handle;
            }

            Result result = vkMergePipelineCaches(Parent, this, count, sourceCachesPtr);

            VulkanException.ThrowForInvalidResult(result);
        }
Esempio n. 23
0
        internal DescriptorPool(Device parent, ref DescriptorPoolCreateInfo createInfo, ref AllocationCallbacks?allocator)
        {
            Parent    = parent;
            Allocator = allocator;

            fixed(DescriptorPoolSize *poolSizesPtr = createInfo.PoolSizes)
            {
                createInfo.ToNative(out DescriptorPoolCreateInfo.Native nativeCreateInfo, poolSizesPtr);
                long   handle;
                Result result = vkCreateDescriptorPool(Parent, &nativeCreateInfo, NativeAllocator, &handle);

                VulkanException.ThrowForInvalidResult(result);
                Handle = handle;
            }
        }
Esempio n. 24
0
        /// <summary>
        /// Create a new Vulkan instance.
        /// </summary>
        /// <param name="createInfo">
        /// An instance of <see cref="InstanceCreateInfo"/> controlling creation of the instance.
        /// </param>
        /// <param name="allocator">Controls host memory allocation.</param>
        /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
        public Instance(InstanceCreateInfo createInfo = default(InstanceCreateInfo),
                        AllocationCallbacks?allocator = null)
        {
            Allocator = allocator;

            createInfo.ToNative(out InstanceCreateInfo.Native nativeCreateInfo);

            IntPtr handle;
            Result result = vkCreateInstance(&nativeCreateInfo, NativeAllocator, &handle);

            nativeCreateInfo.Free();

            VulkanException.ThrowForInvalidResult(result);
            Handle = handle;
        }
Esempio n. 25
0
        internal ShaderModule(Device parent, ref ShaderModuleCreateInfo createInfo, ref AllocationCallbacks?allocator)
        {
            Parent    = parent;
            Allocator = allocator;

            fixed(byte *codePtr = createInfo.Code)
            {
                createInfo.ToNative(out ShaderModuleCreateInfo.Native nativeCreateInfo, codePtr);
                long   handle;
                Result result = vkCreateShaderModule(Parent, &nativeCreateInfo, NativeAllocator, &handle);

                VulkanException.ThrowForInvalidResult(result);
                Handle = handle;
            }
        }
Esempio n. 26
0
        internal Image(Device parent, ref ImageCreateInfo createInfo, ref AllocationCallbacks?allocator)
        {
            Parent    = parent;
            Allocator = allocator;

            fixed(int *queueFamilyIndicesPtr = createInfo.QueueFamilyIndices)
            {
                createInfo.ToNative(out ImageCreateInfo.Native nativeCreateInfo, queueFamilyIndicesPtr);
                long   handle;
                Result result = vkCreateImage(parent, &nativeCreateInfo, NativeAllocator, &handle);

                VulkanException.ThrowForInvalidResult(result);
                Handle = handle;
            }
        }
Esempio n. 27
0
        internal DescriptorSetLayout(Device parent,
                                     ref DescriptorSetLayoutCreateInfo createInfo,
                                     ref AllocationCallbacks?allocator)
        {
            Parent    = parent;
            Allocator = allocator;

            createInfo.ToNative(out DescriptorSetLayoutCreateInfo.Native nativeCreateInfo);
            long   handle;
            Result result = vkCreateDescriptorSetLayout(Parent, &nativeCreateInfo, NativeAllocator, &handle);

            nativeCreateInfo.Free();
            VulkanException.ThrowForInvalidResult(result);
            Handle = handle;
        }
Esempio n. 28
0
        /// <summary>
        /// Get the data store from a pipeline cache.
        /// </summary>
        /// <returns>Buffer.</returns>
        /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
        public byte[] GetData()
        {
            int    size;
            Result result = vkGetPipelineCacheData(Parent, this, &size, null);

            VulkanException.ThrowForInvalidResult(result);

            var data = new byte[size];

            fixed(byte *dataPtr = data)
            result = vkGetPipelineCacheData(Parent, this, &size, dataPtr);

            VulkanException.ThrowForInvalidResult(result);
            return(data);
        }
Esempio n. 29
0
        internal PipelineCache(Device parent, ref PipelineCacheCreateInfo createInfo, ref AllocationCallbacks?allocator)
        {
            Parent    = parent;
            Allocator = allocator;

            fixed(byte *initialDataPtr = createInfo.InitialData)
            {
                createInfo.ToNative(out PipelineCacheCreateInfo.Native nativeCreateInfo, initialDataPtr);
                long   handle;
                Result result = vkCreatePipelineCache(Parent, &nativeCreateInfo, NativeAllocator, &handle);

                VulkanException.ThrowForInvalidResult(result);
                Handle = handle;
            }
        }
Esempio n. 30
0
        internal RenderPass(Device parent, ref RenderPassCreateInfo createInfo, ref AllocationCallbacks?allocator)
        {
            Parent    = parent;
            Allocator = allocator;

            fixed(AttachmentDescription *attachmentsPtr = createInfo.Attachments)
            fixed(SubpassDependency * dependenciesPtr = createInfo.Dependencies)
            {
                createInfo.ToNative(out RenderPassCreateInfo.Native nativeCreateInfo, attachmentsPtr, dependenciesPtr);
                long   handle;
                Result result = vkCreateRenderPass(Parent, &nativeCreateInfo, NativeAllocator, &handle);

                nativeCreateInfo.Free();
                VulkanException.ThrowForInvalidResult(result);
                Handle = handle;
            }
        }