Ejemplo n.º 1
0
        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);
        }
        private void CreateDescriptorSet()
        {
            var allocInfo = new DescriptorSetAllocateInfo()
            {
                DescriptorPool = vkDescriptorPool,
                SetLayouts     = new DescriptorSetLayout[] { vkDescriptorSetLayout },
            };

            vkDescriptorSet = vkDevice.AllocateDescriptorSets(allocInfo)[0];

            var bufferInfo = new DescriptorBufferInfo()
            {
                Buffer = vkUniformBuffer,
                Offset = 0,
                Range  = Marshal.SizeOf <UniformBufferObject>(),
            };

            var descriptorWrite = new WriteDescriptorSet()
            {
                DstSet          = vkDescriptorSet,
                DstBinding      = 0,
                DstArrayElement = 0,
                DescriptorType  = DescriptorType.UniformBuffer,
                DescriptorCount = 1,
                BufferInfo      = new DescriptorBufferInfo[] { bufferInfo },
            };

            vkDevice.UpdateDescriptorSet(descriptorWrite, null);
        }
Ejemplo n.º 3
0
        protected DescriptorSetExample() : base()
        {
            this.DescriptorPool = CreateDescriptorPool();

            this.DescriptorSets = AllocateDescriptorSets();

            DescriptorBufferInfo info = new DescriptorBufferInfo
            {
                Buffer = UniformBuffer,
                Offset = 0,
                Range  = this.UniformBufferSize
            };

            WriteDescriptorSet write = new WriteDescriptorSet
            {
                SType           = StructureType.WriteDescriptorSet,
                DstSet          = this.DescriptorSets[0],
                DescriptorCount = 1,
                DescriptorType  = DescriptorType.UniformBuffer,
                PBufferInfo     = &info,
                DstArrayElement = 0,
                DstBinding      = 0
            };

            VkApi.UpdateDescriptorSets(this.Device, 1, &write, 0, null);
        }
Ejemplo n.º 4
0
        protected override void CreateDescriptorSets()
        {
            var layouts = new DescriptorSetLayout[images.Length];

            for (int i = 0; i < layouts.Length; i++)
            {
                layouts[i] = descriptorSetLayout;
            }
            var allocInfo = new DescriptorSetAllocateInfo
            {
                DescriptorPool     = descriptorPool,
                DescriptorSetCount = (uint)images.Length,
                SetLayouts         = layouts
            };

            descriptorSets = device.AllocateDescriptorSets(allocInfo);
            for (int a = 0; a < descriptorSets.Length; a++)
            {
                var bufferInfo = new DescriptorBufferInfo
                {
                    Buffer = uniformBuffers[a],
                    Offset = 0,
                    Range  = (sizeof(float) * 16) * 3
                };

                var imageInfo = new DescriptorImageInfo
                {
                    ImageLayout = ImageLayout.ShaderReadOnlyOptimal,
                    ImageView   = textureImageView,
                    Sampler     = textureSampler
                };

                //TODO: Dispose this
                var descriptorWrites = new WriteDescriptorSet[]
                {
                    new WriteDescriptorSet
                    {
                        DstSet          = descriptorSets[a],
                        DstBinding      = 0,
                        DstArrayElement = 0,
                        DescriptorType  = DescriptorType.UniformBuffer,
                        DescriptorCount = 1,
                        BufferInfo      = new DescriptorBufferInfo[] { bufferInfo }
                    },
                    new WriteDescriptorSet
                    {
                        DstSet          = descriptorSets[a],
                        DstBinding      = 1,
                        DstArrayElement = 0,
                        DescriptorType  = DescriptorType.CombinedImageSampler,
                        DescriptorCount = 1,
                        ImageInfo       = new DescriptorImageInfo[] { imageInfo }
                    }
                };
                //device.UpdateDescriptorSet(descriptorWrites[0], null);
                //device.UpdateDescriptorSet(descriptorWrites[1], null);
                device.UpdateDescriptorSets(descriptorWrites, null);
            }
        }
Ejemplo n.º 5
0
        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;
            }
        }
Ejemplo n.º 6
0
        public void InitializeBuffers(int setIndex, int baseBinding, int countPerUnit, DescriptorType type)
        {
            Span <DescriptorBufferInfo> infos = stackalloc DescriptorBufferInfo[countPerUnit];

            for (int j = 0; j < countPerUnit; j++)
            {
                infos[j] = new DescriptorBufferInfo()
                {
                    Range = Vk.WholeSize
                };
            }

            UpdateBuffers(setIndex, baseBinding, infos, type);
        }
Ejemplo n.º 7
0
        void UpdateDescriptorSets()
        {
            var uniformBufferInfo = new DescriptorBufferInfo {
                Buffer = uniformBuffer,
                Offset = 0,
                Range  = 2 * sizeof(float)
            };
            var writeDescriptorSet = new WriteDescriptorSet {
                DstSet         = descriptorSets [0],
                DescriptorType = DescriptorType.UniformBuffer,
                BufferInfo     = new DescriptorBufferInfo [] { uniformBufferInfo }
            };

            device.UpdateDescriptorSets(new WriteDescriptorSet [] { writeDescriptorSet }, null);
        }
Ejemplo n.º 8
0
        public void SetStorageBuffers(CommandBuffer commandBuffer, int first, ReadOnlySpan <BufferRange> buffers)
        {
            for (int i = 0; i < buffers.Length; i++)
            {
                var buffer = buffers[i];
                int index  = first + i;

                Auto <DisposableBuffer>     vkBuffer        = _gd.BufferManager.GetBuffer(commandBuffer, buffer.Handle, false);
                ref Auto <DisposableBuffer> currentVkBuffer = ref _storageBufferRefs[index];

                DescriptorBufferInfo info = new DescriptorBufferInfo()
                {
                    Offset = (ulong)buffer.Offset,
                    Range  = (ulong)buffer.Size
                };
                ref DescriptorBufferInfo currentInfo = ref _storageBuffers[index];
Ejemplo n.º 9
0
        public unsafe void UpdateBuffer(int setIndex, int bindingIndex, DescriptorBufferInfo bufferInfo, DescriptorType type)
        {
            if (bufferInfo.Buffer.Handle != 0UL)
            {
                var writeDescriptorSet = new WriteDescriptorSet
                {
                    SType           = StructureType.WriteDescriptorSet,
                    DstSet          = _descriptorSets[setIndex],
                    DstBinding      = (uint)bindingIndex,
                    DescriptorType  = type,
                    DescriptorCount = 1,
                    PBufferInfo     = &bufferInfo
                };

                _holder.Api.UpdateDescriptorSets(_holder.Device, 1, writeDescriptorSet, 0, null);
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Sets a constant buffer view descriptor.
        /// </summary>
        /// <param name="slot">The slot.</param>
        /// <param name="buffer">The constant buffer.</param>
        /// <param name="offset">The constant buffer view start offset.</param>
        /// <param name="size">The constant buffer view size.</param>
        public unsafe void SetConstantBuffer(int slot, Buffer buffer, int offset, int size)
        {
            var bufferInfo = new DescriptorBufferInfo {
                Buffer = buffer.NativeBuffer, Offset = (ulong)offset, Range = (ulong)size
            };

            var write = new WriteDescriptorSet
            {
                sType                   = VkStructureType.WriteDescriptorSet,
                DescriptorCount         = 1,
                DestinationSet          = NativeDescriptorSet,
                DestinationBinding      = (uint)slot,
                DestinationArrayElement = 0,
                VkDescriptorType        = VkDescriptorType.UniformBuffer,
                BufferInfo              = new IntPtr(&bufferInfo)
            };

            GraphicsDevice.NativeDevice.UpdateDescriptorSets(1, &write, 0, null);
        }
Ejemplo n.º 11
0
        public void SetUniformBuffers(CommandBuffer commandBuffer, int first, ReadOnlySpan <BufferRange> buffers)
        {
            Array.Resize(ref _uniformBuffers, first + buffers.Length);
            Array.Resize(ref _uniformBufferRefs, first + buffers.Length);

            for (int i = 0; i < buffers.Length; i++)
            {
                var buffer = buffers[i];

                _uniformBufferRefs[first + i] = _gd.BufferManager.GetBuffer(commandBuffer, buffer.Handle, false);

                _uniformBuffers[first + i] = new DescriptorBufferInfo()
                {
                    Offset = (ulong)buffer.Offset,
                    Range  = (ulong)buffer.Size
                };
            }

            SignalDirty(DirtyFlags.Uniform);
        }
Ejemplo n.º 12
0
        public void CreateDesriptorSets(string bufName, int size)
        {
            DescriptorSetAllocateInfo dsai = new DescriptorSetAllocateInfo(
                mChainImageViews.Length, mDSLs);

            mDSets = mDPool.AllocateSets(dsai);

            for (int i = 0; i < mChainImageViews.Length; i++)
            {
                DescriptorBufferInfo dbi = new DescriptorBufferInfo();

                dbi.Buffer = mBuffers[bufName + i];
                dbi.Range  = size;

                WriteDescriptorSet wds = new WriteDescriptorSet();

                wds.DstSet          = mDSets[i];
                wds.DescriptorType  = DescriptorType.UniformBuffer;
                wds.DescriptorCount = 1;
                wds.BufferInfo      = new DescriptorBufferInfo[] { dbi };

                mDPool.UpdateSets(new WriteDescriptorSet[] { wds });
            }
        }
Ejemplo n.º 13
0
        private void DrawInternal()
        {
            // Update descriptors
            var descriptorSets = stackalloc DescriptorSet[2];
            var setLayouts     = stackalloc DescriptorSetLayout[2];

            setLayouts[0] = setLayouts[1] = descriptorSetLayout;

            var allocateInfo = new DescriptorSetAllocateInfo
            {
                StructureType      = StructureType.DescriptorSetAllocateInfo,
                DescriptorPool     = descriptorPool,
                DescriptorSetCount = 2,
                SetLayouts         = new IntPtr(setLayouts),
            };

            device.AllocateDescriptorSets(ref allocateInfo, descriptorSets);

            var bufferInfo = new DescriptorBufferInfo
            {
                Buffer = uniformBuffer,
                Range  = Vulkan.WholeSize
            };

            var write = new WriteDescriptorSet
            {
                StructureType      = StructureType.WriteDescriptorSet,
                DescriptorCount    = 1,
                DestinationSet     = descriptorSets[0],
                DestinationBinding = 0,
                DescriptorType     = DescriptorType.UniformBuffer,
                BufferInfo         = new IntPtr(&bufferInfo)
            };

            var copy = new CopyDescriptorSet
            {
                StructureType      = StructureType.CopyDescriptorSet,
                DescriptorCount    = 1,
                SourceBinding      = 0,
                DestinationBinding = 0,
                SourceSet          = descriptorSets[0],
                DestinationSet     = descriptorSets[1]
            };

            device.UpdateDescriptorSets(1, &write, 0, null);
            device.UpdateDescriptorSets(0, null, 1, &copy);

            // Post-present transition
            var memoryBarrier = new ImageMemoryBarrier
            {
                StructureType         = StructureType.ImageMemoryBarrier,
                Image                 = backBuffers[currentBackBufferIndex],
                SubresourceRange      = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1),
                OldLayout             = ImageLayout.PresentSource,
                NewLayout             = ImageLayout.ColorAttachmentOptimal,
                SourceAccessMask      = AccessFlags.MemoryRead,
                DestinationAccessMask = AccessFlags.ColorAttachmentWrite
            };

            commandBuffer.PipelineBarrier(PipelineStageFlags.TopOfPipe, PipelineStageFlags.TopOfPipe, DependencyFlags.None, 0, null, 0, null, 1, &memoryBarrier);

            // Clear render target
            var clearRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1);

            commandBuffer.ClearColorImage(backBuffers[currentBackBufferIndex], ImageLayout.TransferDestinationOptimal, new RawColor4(0, 0, 0, 1), 1, &clearRange);

            // Begin render pass
            var renderPassBeginInfo = new RenderPassBeginInfo
            {
                StructureType = StructureType.RenderPassBeginInfo,
                RenderPass    = renderPass,
                Framebuffer   = framebuffers[currentBackBufferIndex],
                RenderArea    = new Rect2D(0, 0, (uint)form.ClientSize.Width, (uint)form.ClientSize.Height),
            };

            commandBuffer.BeginRenderPass(ref renderPassBeginInfo, SubpassContents.Inline);

            // Bind pipeline
            commandBuffer.BindPipeline(PipelineBindPoint.Graphics, pipeline);

            // Bind descriptor sets
            commandBuffer.BindDescriptorSets(PipelineBindPoint.Graphics, pipelineLayout, 0, 1, descriptorSets + 1, 0, null);

            // Set viewport and scissor
            var viewport = new Viewport(0, 0, form.ClientSize.Width, form.ClientSize.Height);

            commandBuffer.SetViewport(0, 1, &viewport);

            var scissor = new Rect2D(0, 0, (uint)form.ClientSize.Width, (uint)form.ClientSize.Height);

            commandBuffer.SetScissor(0, 1, &scissor);

            // Bind vertex buffer
            var   vertexBufferCopy = vertexBuffer;
            ulong offset           = 0;

            commandBuffer.BindVertexBuffers(0, 1, &vertexBufferCopy, &offset);

            // Draw vertices
            commandBuffer.Draw(3, 1, 0, 0);

            // End render pass
            commandBuffer.EndRenderPass();

            // Pre-present transition
            memoryBarrier = new ImageMemoryBarrier
            {
                StructureType         = StructureType.ImageMemoryBarrier,
                Image                 = backBuffers[currentBackBufferIndex],
                SubresourceRange      = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1),
                OldLayout             = ImageLayout.ColorAttachmentOptimal,
                NewLayout             = ImageLayout.PresentSource,
                SourceAccessMask      = AccessFlags.ColorAttachmentWrite,
                DestinationAccessMask = AccessFlags.MemoryRead
            };
            commandBuffer.PipelineBarrier(PipelineStageFlags.AllCommands, PipelineStageFlags.BottomOfPipe, DependencyFlags.None, 0, null, 0, null, 1, &memoryBarrier);
        }
Ejemplo n.º 14
0
        void CreateDescriptorSet()
        {
            /*
             * So we will allocate a descriptor set here.
             * But we need to first create a descriptor pool to do that.
             */

            /*
             * Our descriptor pool can only allocate a single storage buffer.
             */
            DescriptorPoolSize descriptorPoolSize = new DescriptorPoolSize()
            {
                Type            = DescriptorType.StorageBuffer,// VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
                DescriptorCount = 1
            };
            DescriptorPoolCreateInfo descriptorPoolCreateInfo = new DescriptorPoolCreateInfo()
            {
                MaxSets   = 1, // we only need to allocate one descriptor set from the pool.
                Flags     = DescriptorPoolCreateFlags.FreeDescriptorSet,
                PoolSizes = new[] { descriptorPoolSize }
            };

            // create descriptor pool.
            descriptorPool = device.CreateDescriptorPool(descriptorPoolCreateInfo);

            /*
             * With the pool allocated, we can now allocate the descriptor set.
             */
            DescriptorSetAllocateInfo descriptorSetAllocateInfo = new DescriptorSetAllocateInfo(1, descriptorSetLayout);

            // allocate a single descriptor set.

            // allocate descriptor set.
            descriptorSet = descriptorPool.AllocateSets(descriptorSetAllocateInfo)[0];

            /*
             * Next, we need to connect our actual storage buffer with the descrptor.
             * We use vkUpdateDescriptorSets() to update the descriptor set.
             */

            // Specify the buffer to bind to the descriptor.
            DescriptorBufferInfo descriptorBufferInfo = new DescriptorBufferInfo()
            {
                Buffer = buffer,
                Offset = 0,
                Range  = bufferSize
            };
            WriteDescriptorSet writeDescriptorSet = new WriteDescriptorSet()
            {
                DstSet          = descriptorSet,                // write to this descriptor set.
                DstBinding      = 0,                            // write to the first, and only binding.
                DstArrayElement = 0,
                DescriptorCount = 1,                            // update a single descriptor.
                DescriptorType  = DescriptorType.StorageBuffer, // VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; // storage buffer.
                BufferInfo      = new[] { descriptorBufferInfo }
            };

            // perform the update of the descriptor set.
            WriteDescriptorSet[] k = { writeDescriptorSet };
            descriptorPool.UpdateSets(k);
        }
Ejemplo n.º 15
0
        public unsafe void Run(int currentFrameIndex, int imageIndex, Semaphore waitSemaphore, Semaphore signalSemaphore, Fence signal)
        {
            var bufferInfo = new DescriptorBufferInfo(_commandBuffers[currentFrameIndex], 0,
                                                      (ulong)(sizeof(uint) * _commandBufferCapacities[currentFrameIndex]));

            _vk.UpdateDescriptorSets(_device, 1,
                                     new WriteDescriptorSet(dstSet: _targetDescriptorSets[currentFrameIndex], dstBinding: 1, dstArrayElement: 0,
                                                            descriptorCount: 1, descriptorType: DescriptorType.StorageBuffer, pBufferInfo: &bufferInfo), 0,
                                     null);


            var currentFrame = _frames[currentFrameIndex];

            _vk.ResetCommandPool(_device, currentFrame.CommandPool, 0).ThrowCode();
            _vk.AllocateCommandBuffers(_device,
                                       new CommandBufferAllocateInfo(commandPool: currentFrame.CommandPool, level: CommandBufferLevel.Primary,
                                                                     commandBufferCount: 1), out var commandBuffer).ThrowCode();

            Name(ObjectType.CommandBuffer, (ulong)commandBuffer.Handle, $"Command Buffer Frame {currentFrameIndex}");

            var renderContext = new RenderContext(_targetImageViews[imageIndex],
                                                  _targetSize, currentFrameIndex);

            _vk.BeginCommandBuffer(commandBuffer,
                                   new CommandBufferBeginInfo(flags: CommandBufferUsageFlags.CommandBufferUsageOneTimeSubmitBit))
            .ThrowCode();

            // var memoryBarrier = new ImageMemoryBarrier2KHR(srcStageMask: PipelineStageFlags2KHR.PipelineStage2TopOfPipeBitKhr,
            //     srcAccessMask: AccessFlags2KHR.Access2NoneKhr, dstStageMask: PipelineStageFlags2KHR.PipelineStage2TransferBitKhr,
            //     dstAccessMask: AccessFlags2KHR.Access2TransferWriteBitKhr,
            //     oldLayout: ImageLayout.Undefined, newLayout: ImageLayout.TransferDstOptimal,
            //     srcQueueFamilyIndex: Vk.QueueFamilyIgnored, dstQueueFamilyIndex: Vk.QueueFamilyIgnored,
            //     image: _targetImages.Span[imageIndex], subresourceRange: new ImageSubresourceRange(ImageAspectFlags.ImageAspectColorBit, 0, 1, 0, 1),
            //     sType: StructureType.ImageMemoryBarrier2Khr, pNext: null);
            // _khrSynchronization2.CmdPipelineBarrier2(commandBuffer, new DependencyInfoKHR(imageMemoryBarrierCount: 1,
            //     pImageMemoryBarriers: &memoryBarrier, dependencyFlags: 0, memoryBarrierCount: 0, pMemoryBarriers: null, bufferMemoryBarrierCount: 0, pBufferMemoryBarriers: null));

            _vk.CmdPipelineBarrier(commandBuffer, PipelineStageFlags.PipelineStageTopOfPipeBit,
                                   PipelineStageFlags.PipelineStageTransferBit, 0, 0, null, 0, null, 1,
                                   new ImageMemoryBarrier(srcAccessMask: AccessFlags.AccessNoneKhr,
                                                          dstAccessMask: AccessFlags.AccessTransferWriteBit, oldLayout: ImageLayout.Undefined,
                                                          newLayout: ImageLayout.TransferDstOptimal, srcQueueFamilyIndex: Vk.QueueFamilyIgnored,
                                                          dstQueueFamilyIndex: Vk.QueueFamilyIgnored, image: _targetImages.Span[imageIndex],
                                                          subresourceRange: new ImageSubresourceRange(ImageAspectFlags.ImageAspectColorBit, 0, 1, 0, 1)));

            _vk.CmdClearColorImage(commandBuffer, _targetImages.Span[imageIndex], ImageLayout.TransferDstOptimal,
                                   new ClearColorValue(0f, 0f, 0f, 1f), 1,
                                   new ImageSubresourceRange(ImageAspectFlags.ImageAspectColorBit, 0, 1, 0, 1));

            // var memoryBarrier2 = new ImageMemoryBarrier2KHR(srcStageMask: PipelineStageFlags2KHR.PipelineStage2TransferBitKhr,
            //     srcAccessMask: AccessFlags2KHR.Access2TransferWriteBitKhr, dstStageMask: PipelineStageFlags2KHR.PipelineStage2ComputeShaderBitKhr,
            //     dstAccessMask: AccessFlags2KHR.Access2ShaderReadBitKhr | AccessFlags2KHR.Access2ShaderWriteBitKhr,
            //     oldLayout: ImageLayout.TransferDstOptimal, newLayout: ImageLayout.General,
            //     srcQueueFamilyIndex: Vk.QueueFamilyIgnored, dstQueueFamilyIndex: Vk.QueueFamilyIgnored,
            //     image: _targetImages.Span[imageIndex], subresourceRange: new ImageSubresourceRange(ImageAspectFlags.ImageAspectColorBit, 0, 1, 0, 1));
            // _khrSynchronization2.CmdPipelineBarrier2(commandBuffer, new DependencyInfoKHR(imageMemoryBarrierCount: 1,
            //     pImageMemoryBarriers: &memoryBarrier2));

            _vk.CmdPipelineBarrier(commandBuffer, PipelineStageFlags.PipelineStageTransferBit,
                                   PipelineStageFlags.PipelineStageComputeShaderBit, 0, 0, null, 0, null, 1,
                                   new ImageMemoryBarrier(srcAccessMask: AccessFlags.AccessTransferWriteBit,
                                                          dstAccessMask: AccessFlags.AccessShaderReadBit | AccessFlags.AccessShaderWriteBit, oldLayout: ImageLayout.TransferDstOptimal,
                                                          newLayout: ImageLayout.General, srcQueueFamilyIndex: Vk.QueueFamilyIgnored,
                                                          dstQueueFamilyIndex: Vk.QueueFamilyIgnored, image: _targetImages.Span[imageIndex],
                                                          subresourceRange: new ImageSubresourceRange(ImageAspectFlags.ImageAspectColorBit, 0, 1, 0, 1)));

            Span <uint> pValues = stackalloc uint[]
            {
                _targetSize.X, _targetSize.Y
            };

            _vk.CmdPushConstants(commandBuffer, _pipelineLayout, ShaderStageFlags.ShaderStageComputeBit, 0, (uint)pValues.Length * sizeof(uint), pValues);
            _vk.CmdBindDescriptorSets(commandBuffer, PipelineBindPoint.Compute, _pipelineLayout, 0, 1,
                                      _targetDescriptorSets[imageIndex], 0, null);
            _computeShader.Record(renderContext, commandBuffer);

            // var memoryBarrier3 = new ImageMemoryBarrier2KHR(srcStageMask: PipelineStageFlags2KHR.PipelineStage2ComputeShaderBitKhr,
            //      srcAccessMask: AccessFlags2KHR.Access2ShaderReadBitKhr | AccessFlags2KHR.Access2ShaderWriteBitKhr, dstStageMask: PipelineStageFlags2KHR.PipelineStage2BottomOfPipeBitKhr,
            //      dstAccessMask: AccessFlags2KHR.Access2NoneKhr,
            //      oldLayout: ImageLayout.General, newLayout: ImageLayout.PresentSrcKhr,
            //      srcQueueFamilyIndex: Vk.QueueFamilyIgnored, dstQueueFamilyIndex: Vk.QueueFamilyIgnored,
            //      image: _targetImages.Span[imageIndex], subresourceRange: new ImageSubresourceRange(ImageAspectFlags.ImageAspectColorBit, 0, 1, 0, 1));
            //  _khrSynchronization2.CmdPipelineBarrier2(commandBuffer, new DependencyInfoKHR(imageMemoryBarrierCount: 1,
            //      pImageMemoryBarriers: &memoryBarrier3));

            _vk.CmdPipelineBarrier(commandBuffer, PipelineStageFlags.PipelineStageComputeShaderBit,
                                   PipelineStageFlags.PipelineStageBottomOfPipeBit, 0, 0, null, 0, null, 1,
                                   new ImageMemoryBarrier(srcAccessMask: AccessFlags.AccessShaderReadBit | AccessFlags.AccessShaderWriteBit,
                                                          dstAccessMask: AccessFlags.AccessNoneKhr, oldLayout: ImageLayout.General,
                                                          newLayout: ImageLayout.PresentSrcKhr, srcQueueFamilyIndex: Vk.QueueFamilyIgnored,
                                                          dstQueueFamilyIndex: Vk.QueueFamilyIgnored, image: _targetImages.Span[imageIndex],
                                                          subresourceRange: new ImageSubresourceRange(ImageAspectFlags.ImageAspectColorBit, 0, 1, 0, 1)));

            _vk.EndCommandBuffer(commandBuffer);

            var waitDstStageMask = PipelineStageFlags.PipelineStageTransferBit;

            _vk.QueueSubmit(Queue, 1,
                            new SubmitInfo(waitSemaphoreCount: 1, pWaitSemaphores: &waitSemaphore, commandBufferCount: 1,
                                           pCommandBuffers: &commandBuffer, signalSemaphoreCount: 1, pSignalSemaphores: &signalSemaphore,
                                           pWaitDstStageMask: &waitDstStageMask), signal).ThrowCode();
        }
Ejemplo n.º 16
0
        private void DrawInternal()
        {
            // Update descriptors
            var descriptorSets = stackalloc DescriptorSet[2];
            var setLayouts = stackalloc DescriptorSetLayout[2];
            setLayouts[0] = setLayouts[1] = descriptorSetLayout;

            var allocateInfo = new DescriptorSetAllocateInfo
            {
                StructureType = StructureType.DescriptorSetAllocateInfo,
                DescriptorPool = descriptorPool,
                DescriptorSetCount = 2,
                SetLayouts = new IntPtr(setLayouts),
            };
            device.AllocateDescriptorSets(ref allocateInfo, descriptorSets);

            var bufferInfo = new DescriptorBufferInfo
            {
                Buffer = uniformBuffer,
                Range = Vulkan.WholeSize
            };

            var write = new WriteDescriptorSet
            {
                StructureType = StructureType.WriteDescriptorSet,
                DescriptorCount = 1,
                DestinationSet = descriptorSets[0],
                DestinationBinding = 0,
                DescriptorType = DescriptorType.UniformBuffer,
                BufferInfo = new IntPtr(&bufferInfo)
            };

            var copy = new CopyDescriptorSet
            {
                StructureType = StructureType.CopyDescriptorSet,
                DescriptorCount = 1,
                SourceBinding = 0,
                DestinationBinding = 0,
                SourceSet = descriptorSets[0],
                DestinationSet = descriptorSets[1]
            };

            device.UpdateDescriptorSets(1, &write, 0, null);
            device.UpdateDescriptorSets(0, null, 1, &copy);

            // Post-present transition
            var memoryBarrier = new ImageMemoryBarrier
            {
                StructureType = StructureType.ImageMemoryBarrier,
                Image = backBuffers[currentBackBufferIndex],
                SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1),
                OldLayout = ImageLayout.PresentSource,
                NewLayout = ImageLayout.ColorAttachmentOptimal,
                SourceAccessMask = AccessFlags.MemoryRead,
                DestinationAccessMask = AccessFlags.ColorAttachmentWrite
            };
            commandBuffer.PipelineBarrier(PipelineStageFlags.TopOfPipe, PipelineStageFlags.TopOfPipe, DependencyFlags.None, 0, null, 0, null, 1, &memoryBarrier);

            // Clear render target
            var clearRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1);
            commandBuffer.ClearColorImage(backBuffers[currentBackBufferIndex], ImageLayout.TransferDestinationOptimal, new RawColor4(0, 0, 0, 1), 1, &clearRange);

            // Begin render pass
            var renderPassBeginInfo = new RenderPassBeginInfo
            {
                StructureType = StructureType.RenderPassBeginInfo,
                RenderPass = renderPass,
                Framebuffer = framebuffers[currentBackBufferIndex],
                RenderArea = new Rect2D(0, 0, (uint)form.ClientSize.Width, (uint)form.ClientSize.Height),
            };
            commandBuffer.BeginRenderPass(ref renderPassBeginInfo, SubpassContents.Inline);

            // Bind pipeline
            commandBuffer.BindPipeline(PipelineBindPoint.Graphics, pipeline);

            // Bind descriptor sets
            commandBuffer.BindDescriptorSets(PipelineBindPoint.Graphics, pipelineLayout, 0, 1, descriptorSets + 1, 0, null);

            // Set viewport and scissor
            var viewport = new Viewport(0, 0, form.ClientSize.Width, form.ClientSize.Height);
            commandBuffer.SetViewport(0, 1, &viewport);

            var scissor = new Rect2D(0, 0, (uint)form.ClientSize.Width, (uint)form.ClientSize.Height);
            commandBuffer.SetScissor(0, 1, &scissor);

            // Bind vertex buffer
            var vertexBufferCopy = vertexBuffer;
            ulong offset = 0;
            commandBuffer.BindVertexBuffers(0, 1, &vertexBufferCopy, &offset);

            // Draw vertices
            commandBuffer.Draw(3, 1, 0, 0);

            // End render pass
            commandBuffer.EndRenderPass();

            // Pre-present transition
            memoryBarrier = new ImageMemoryBarrier
            {
                StructureType = StructureType.ImageMemoryBarrier,
                Image = backBuffers[currentBackBufferIndex],
                SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1),
                OldLayout = ImageLayout.ColorAttachmentOptimal,
                NewLayout = ImageLayout.PresentSource,
                SourceAccessMask = AccessFlags.ColorAttachmentWrite,
                DestinationAccessMask = AccessFlags.MemoryRead
            };
            commandBuffer.PipelineBarrier(PipelineStageFlags.AllCommands, PipelineStageFlags.BottomOfPipe, DependencyFlags.None, 0, null, 0, null, 1, &memoryBarrier);
        }
Ejemplo n.º 17
0
        private void UpdateAndBind(CommandBufferScoped cbs, int setIndex, DirtyFlags flag, PipelineBindPoint pbp)
        {
            int stagesCount = _program.Bindings[setIndex].Length;

            if (stagesCount == 0 && setIndex != PipelineBase.UniformSetIndex)
            {
                return;
            }

            var dsc = _program.GetNewDescriptorSetCollection(_gd, cbs.CommandBufferIndex, setIndex, out var isNew).Get(cbs);

            if (isNew)
            {
                Initialize(cbs, setIndex, dsc);
            }

            if (setIndex == PipelineBase.UniformSetIndex)
            {
                Span <DescriptorBufferInfo> uniformBuffer = stackalloc DescriptorBufferInfo[1];

                uniformBuffer[0] = new DescriptorBufferInfo()
                {
                    Offset = 0,
                    Range  = SupportBuffer.RequiredSize,
                    Buffer = _pipeline.RenderScaleBuffer.GetBuffer().Get(cbs, 0, SupportBuffer.RequiredSize).Value
                };

                dsc.UpdateBuffers(0, 0, uniformBuffer, DescriptorType.UniformBuffer);
            }

            for (int stageIndex = 0; stageIndex < stagesCount; stageIndex++)
            {
                var stageBindings = _program.Bindings[setIndex][stageIndex];
                int bindingsCount = stageBindings.Length;
                int count;

                for (int bindingIndex = 0; bindingIndex < bindingsCount; bindingIndex += count)
                {
                    int binding = stageBindings[bindingIndex];
                    count = 1;

                    while (bindingIndex + count < bindingsCount && stageBindings[bindingIndex + count] == binding + count)
                    {
                        count++;
                    }

                    if (setIndex == PipelineBase.UniformSetIndex)
                    {
                        count = Math.Min(count, _uniformBuffers.Length - binding);

                        if (count <= 0)
                        {
                            break;
                        }

                        for (int i = 0; i < count; i++)
                        {
                            UpdateBuffer(cbs, ref _uniformBuffers[binding + i], _uniformBufferRefs[binding + i]);
                        }

                        ReadOnlySpan <DescriptorBufferInfo> uniformBuffers = _uniformBuffers;
                        dsc.UpdateBuffers(0, binding, uniformBuffers.Slice(binding, count), DescriptorType.UniformBuffer);
                    }
                    else if (setIndex == PipelineBase.StorageSetIndex)
                    {
                        count = Math.Min(count, _storageBuffers.Length - binding);

                        if (count <= 0)
                        {
                            break;
                        }

                        for (int i = 0; i < count; i++)
                        {
                            UpdateBuffer(cbs, ref _storageBuffers[binding + i], _storageBufferRefs[binding + i]);
                        }

                        ReadOnlySpan <DescriptorBufferInfo> storageBuffers = _storageBuffers;
                        dsc.UpdateStorageBuffers(0, binding, storageBuffers.Slice(binding, count));
                    }
                    else if (setIndex == PipelineBase.TextureSetIndex)
                    {
                        for (int i = 0; i < count; i++)
                        {
                            ref var texture = ref _textures[binding + i];

                            texture.ImageView   = _textureRefs[binding + i]?.Get(cbs).Value ?? default;
                            texture.Sampler     = _samplerRefs[binding + i]?.Get(cbs).Value ?? default;
                            texture.ImageLayout = ImageLayout.General;

                            if (texture.ImageView.Handle == 0 || texture.Sampler.Handle == 0)
                            {
                                texture.ImageView = _dummyTexture.GetImageView().Get(cbs).Value;
                                texture.Sampler   = _dummySampler.GetSampler().Get(cbs).Value;
                            }
                        }

                        ReadOnlySpan <DescriptorImageInfo> textures = _textures;
                        dsc.UpdateImages(0, binding, textures.Slice(binding, count), DescriptorType.CombinedImageSampler);
                    }
Ejemplo n.º 18
0
        static public MPointArray ComputeData(MPointArray inPos, float angle, float envolope)
        {
            var memorySize = inPos.Count * 4 * sizeof(float);

            float[] ubo = { inPos.Count, angle, envolope };

            // pos to float[]
            float[] allPos = new float[inPos.Count * 4];
            var     i      = 0;

            foreach (var point in inPos)
            {
                allPos[i * 4 + 0] = (float)point.x;
                allPos[i * 4 + 1] = (float)point.y;
                allPos[i * 4 + 2] = (float)point.z;
                allPos[i * 4 + 3] = (float)point.w;
                i++;
            }

            var instance = new Instance(new InstanceCreateInfo {
                ApplicationInfo = new ApplicationInfo {
                    ApplicationName    = "CSharp Vulkan",
                    ApplicationVersion = Vulkan.Version.Make(1, 0, 0),
                    ApiVersion         = Vulkan.Version.Make(1, 0, 0),
                    EngineName         = "CSharp Engine",
                    EngineVersion      = Vulkan.Version.Make(1, 0, 0)
                },
                //EnabledExtensionCount = 0,
                //EnabledLayerCount = 0
                EnabledExtensionNames = new string[] { "VK_EXT_debug_report" },
                EnabledLayerNames     = new string[] { "VK_LAYER_LUNARG_standard_validation" }
            });

            var debugCallback = new Instance.DebugReportCallback(DebugReportCallback);

            instance.EnableDebug(debugCallback, DebugReportFlagsExt.Warning | DebugReportFlagsExt.Error);

            PhysicalDevice physicalDevice = instance.EnumeratePhysicalDevices()[0];

            var queueFamilyIndex = FindBestComputeQueue(physicalDevice);

            DeviceQueueCreateInfo[] deviceQueueCreateInfo =
            {
                new DeviceQueueCreateInfo
                {
                    QueueFamilyIndex = queueFamilyIndex,
                    QueueCount       = 1,
                    QueuePriorities  = new float[] { 1.0f }
                }
            };

            var deviceCreateInfo = new DeviceCreateInfo
            {
                QueueCreateInfos      = deviceQueueCreateInfo,
                EnabledFeatures       = new PhysicalDeviceFeatures(),
                EnabledExtensionCount = 0,
                //EnabledLayerCount = 0
                //EnabledExtensionNames = new string[] { "VK_EXT_debug_report" },
                EnabledLayerNames = new string[] { "VK_LAYER_LUNARG_standard_validation" }
            };

            var device = physicalDevice.CreateDevice(deviceCreateInfo);

            //var memProperties = physicalDevice.GetMemoryProperties();

            var bufferCreateInfo = new BufferCreateInfo
            {
                Size               = memorySize,
                Usage              = BufferUsageFlags.StorageBuffer,
                SharingMode        = SharingMode.Exclusive,
                QueueFamilyIndices = new uint[] { queueFamilyIndex }
            };

            var inBuffer  = device.CreateBuffer(bufferCreateInfo);
            var outBuffer = device.CreateBuffer(bufferCreateInfo);

            var memRequirements = device.GetBufferMemoryRequirements(inBuffer);

            uint memIndex = FindMemoryType(physicalDevice, memRequirements.MemoryTypeBits, MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent);

            var memoryAllocatInfo = new MemoryAllocateInfo
            {
                AllocationSize  = memRequirements.Size,
                MemoryTypeIndex = memIndex
            };

            var memory = device.AllocateMemory(memoryAllocatInfo);

            var dataPtr = device.MapMemory(memory, 0, memorySize);

            Marshal.Copy(allPos, 0, dataPtr, allPos.Length);

            device.UnmapMemory(memory);

            memRequirements = device.GetBufferMemoryRequirements(outBuffer);
            memoryAllocatInfo.MemoryTypeIndex = FindMemoryType(physicalDevice, memRequirements.MemoryTypeBits, MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent);
            var outMemory = device.AllocateMemory(memoryAllocatInfo);

            device.BindBufferMemory(inBuffer, memory, 0);
            device.BindBufferMemory(outBuffer, outMemory, 0);

            //var uboSize = Marshal.SizeOf(ubo);
            var uboSize             = 3 * sizeof(float);
            var uboBufferCreateInfo = new BufferCreateInfo
            {
                Size               = uboSize,
                Usage              = BufferUsageFlags.UniformBuffer,
                SharingMode        = SharingMode.Exclusive,
                QueueFamilyIndices = new uint[] { queueFamilyIndex }
            };

            var uboBuffer = device.CreateBuffer(uboBufferCreateInfo);

            memRequirements = device.GetBufferMemoryRequirements(uboBuffer);

            var uboMemoryAllocInfo = new MemoryAllocateInfo
            {
                AllocationSize  = memRequirements.Size,
                MemoryTypeIndex = FindMemoryType(physicalDevice, memRequirements.MemoryTypeBits, MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent)
            };

            var uboMemory = device.AllocateMemory(uboMemoryAllocInfo);
            var uboPtr    = device.MapMemory(uboMemory, 0, uboSize);

            Marshal.Copy(ubo, 0, uboPtr, ubo.Length);
            device.UnmapMemory(uboMemory);

            device.BindBufferMemory(uboBuffer, uboMemory, 0);

            //string textureName = string.Format("{0}.comp.spv", typeof(VulankCompute).Namespace);
            //Stream stream = typeof(VulankCompute).GetTypeInfo().Assembly.GetManifestResourceStream(textureName);
            string shaderFile = @"E:\coding\CShape\yTwistCSharpVulkan\comp.spv";
            Stream stream     = File.Open(shaderFile, FileMode.Open);

            byte[] shaderCode = new byte[stream.Length];
            stream.Read(shaderCode, 0, (int)stream.Length);
            stream.Close();
            stream.Dispose();
            var shaderModule = device.CreateShaderModule(shaderCode);

            DescriptorSetLayoutBinding[] descriptorSetLayoutBindings =
            {
                new DescriptorSetLayoutBinding
                {
                    Binding         = 0,
                    DescriptorType  = DescriptorType.StorageBuffer,
                    DescriptorCount = 1,
                    StageFlags      = ShaderStageFlags.Compute
                },

                new DescriptorSetLayoutBinding
                {
                    Binding         = 1,
                    DescriptorType  = DescriptorType.StorageBuffer,
                    DescriptorCount = 1,
                    StageFlags      = ShaderStageFlags.Compute
                },

                new DescriptorSetLayoutBinding
                {
                    Binding         = 2,
                    DescriptorType  = DescriptorType.UniformBuffer,
                    DescriptorCount = 1,
                    StageFlags      = ShaderStageFlags.Compute
                }
            };

            var descriporSetLayoutCreateinfo = new DescriptorSetLayoutCreateInfo
            {
                Bindings = descriptorSetLayoutBindings
            };

            var descriptorSetLayout = device.CreateDescriptorSetLayout(descriporSetLayoutCreateinfo);

            var descriptorPool = device.CreateDescriptorPool(new DescriptorPoolCreateInfo
            {
                MaxSets   = 1,
                PoolSizes = new DescriptorPoolSize[]
                {
                    new DescriptorPoolSize
                    {
                        DescriptorCount = 3
                    }
                }
            });

            var descriptorSet = device.AllocateDescriptorSets(new DescriptorSetAllocateInfo
            {
                DescriptorPool = descriptorPool,
                SetLayouts     = new DescriptorSetLayout[] { descriptorSetLayout }
            })[0];

            var inBufferInfo = new DescriptorBufferInfo
            {
                Buffer = inBuffer,
                Offset = 0,
                Range  = memorySize
            };

            var outBufferInfo = new DescriptorBufferInfo
            {
                Buffer = outBuffer,
                Offset = 0,
                Range  = memorySize
            };

            var uboBufferInfo = new DescriptorBufferInfo
            {
                Buffer = uboBuffer,
                Offset = 0,
                Range  = uboSize
            };

            WriteDescriptorSet[] writeDescriptorSets =
            {
                new WriteDescriptorSet
                {
                    DstSet          = descriptorSet,
                    DstBinding      = 0,
                    DstArrayElement = 0,
                    DescriptorCount = 1,
                    DescriptorType  = DescriptorType.StorageBuffer,
                    BufferInfo      = new DescriptorBufferInfo[] { inBufferInfo }
                },

                new WriteDescriptorSet
                {
                    DstSet          = descriptorSet,
                    DstBinding      = 1,
                    DstArrayElement = 0,
                    DescriptorCount = 1,
                    DescriptorType  = DescriptorType.StorageBuffer,
                    BufferInfo      = new DescriptorBufferInfo[] { outBufferInfo }
                },

                new WriteDescriptorSet
                {
                    DstSet          = descriptorSet,
                    DstBinding      = 2,
                    DstArrayElement = 0,
                    DescriptorCount = 1,
                    DescriptorType  = DescriptorType.UniformBuffer,
                    BufferInfo      = new DescriptorBufferInfo[] { uboBufferInfo }
                }
            };

            device.UpdateDescriptorSets(writeDescriptorSets, null);

            var pipelineLayout = device.CreatePipelineLayout(new PipelineLayoutCreateInfo
            {
                SetLayouts = new DescriptorSetLayout[] { descriptorSetLayout }
            });

            var shaderStage = new PipelineShaderStageCreateInfo
            {
                Stage  = ShaderStageFlags.Compute,
                Module = shaderModule,
                Name   = "main"
            };

            var pipeline = device.CreateComputePipelines(null, new ComputePipelineCreateInfo[]
            {
                new ComputePipelineCreateInfo
                {
                    Stage  = shaderStage,
                    Layout = pipelineLayout
                }
            })[0];

            var commandPool = device.CreateCommandPool(new CommandPoolCreateInfo
            {
                QueueFamilyIndex = queueFamilyIndex
            });

            var cmdBuffer = device.AllocateCommandBuffers(new CommandBufferAllocateInfo
            {
                CommandPool        = commandPool,
                CommandBufferCount = 1,
                Level = CommandBufferLevel.Primary
            })[0];

            cmdBuffer.Begin(new CommandBufferBeginInfo
            {
                Flags = CommandBufferUsageFlags.OneTimeSubmit
            });

            cmdBuffer.CmdBindPipeline(PipelineBindPoint.Compute, pipeline);

            cmdBuffer.CmdBindDescriptorSet(PipelineBindPoint.Compute, pipelineLayout, 0, descriptorSet, null);

            cmdBuffer.CmdDispatch((uint)inPos.Count, 1, 1);

            cmdBuffer.End();

            var queue = device.GetQueue(queueFamilyIndex, 0);

            //var fence = device.CreateFence(new FenceCreateInfo { Flags=0 });
            queue.Submit(new SubmitInfo
            {
                WaitSemaphoreCount = 0,
                CommandBuffers     = new CommandBuffer[] { cmdBuffer },
            });
            queue.WaitIdle();
            //device.WaitForFence(fence, true, UInt64.MaxValue);

            var newDataPtr = device.MapMemory(outMemory, 0, memorySize);

            Marshal.Copy(newDataPtr, allPos, 0, allPos.Length);
            device.UnmapMemory(outMemory);

            var j = 0;

            foreach (var p in inPos)
            {
                p.x = allPos[j * 4 + 0];
                p.y = allPos[j * 4 + 1];
                p.z = allPos[j * 4 + 2];
                p.w = allPos[j * 4 + 3];
                j++;
            }

            //device.DestroyFence(fence);
            device.DestroyShaderModule(shaderModule);
            device.DestroyCommandPool(commandPool);
            device.DestroyDescriptorSetLayout(descriptorSetLayout);
            device.DestroyDescriptorPool(descriptorPool);
            device.DestroyPipelineLayout(pipelineLayout);
            device.DestroyPipeline(pipeline);
            device.DestroyBuffer(inBuffer);
            device.DestroyBuffer(outBuffer);
            device.DestroyBuffer(uboBuffer);
            device.FreeMemory(memory);
            device.FreeMemory(outMemory);
            device.FreeMemory(uboMemory);
            device.Destroy();

            //instance.Destroy();

            return(inPos);
        }
Ejemplo n.º 19
0
        public unsafe RayTracingPipeline(
            Api api,
            SwapChain swapChain,
            TopLevelAccelerationStructure accelerationStructure,
            ImageView accumulationImageView,
            ImageView outputImageView,
            List <UniformBuffer> uniformBuffers,
            VulkanScene scene)
        {
            (_api, _swapChain) = (api, swapChain);

            // Create descriptor pool/sets.
            var descriptorBindings = new DescriptorBinding[]
            {
                // Top level acceleration structure.
                new DescriptorBinding(0, 1, DescriptorType.AccelerationStructureKhr, ShaderStageFlags.ShaderStageRaygenBitKhr),

                // Image accumulation & output
                new DescriptorBinding(1, 1, DescriptorType.StorageImage, ShaderStageFlags.ShaderStageRaygenBitKhr),
                new DescriptorBinding(2, 1, DescriptorType.StorageImage, ShaderStageFlags.ShaderStageRaygenBitKhr),

                // Camera information & co
                new DescriptorBinding(3, 1, DescriptorType.UniformBuffer, ShaderStageFlags.ShaderStageRaygenBitKhr | ShaderStageFlags.ShaderStageMissBitKhr),

                // Vertex buffer, Index buffer, Material buffer, Offset buffer, Transform buffer
                new DescriptorBinding(4, 1, DescriptorType.StorageBuffer, ShaderStageFlags.ShaderStageClosestHitBitKhr),
                new DescriptorBinding(5, 1, DescriptorType.StorageBuffer, ShaderStageFlags.ShaderStageClosestHitBitKhr),
                new DescriptorBinding(6, 1, DescriptorType.StorageBuffer, ShaderStageFlags.ShaderStageClosestHitBitKhr),
                new DescriptorBinding(7, 1, DescriptorType.StorageBuffer, ShaderStageFlags.ShaderStageClosestHitBitKhr),
                new DescriptorBinding(8, 1, DescriptorType.StorageBuffer, ShaderStageFlags.ShaderStageClosestHitBitKhr | ShaderStageFlags.ShaderStageIntersectionBitKhr),

                // Textures and image samplers
                new DescriptorBinding(9, (uint)scene.TextureSamplers.Count, DescriptorType.CombinedImageSampler, ShaderStageFlags.ShaderStageClosestHitBitKhr),

                // The Procedural buffer.
                new DescriptorBinding(10, 1, DescriptorType.StorageBuffer, ShaderStageFlags.ShaderStageClosestHitBitKhr | ShaderStageFlags.ShaderStageIntersectionBitKhr),
            };

            _descriptorSetManager = new DescriptorSetManager(_api, descriptorBindings, (ulong)uniformBuffers.Count);

            var descriptorSets = _descriptorSetManager.DescriptorSets;

            for (int i = 0; i != swapChain.VkImages.Count; i++)
            {
                // Top level acceleration structure.
                var _structureInfo = new WriteDescriptorSetAccelerationStructureKHR();
                _structureInfo.SType = StructureType.WriteDescriptorSetAccelerationStructureKhr;
                _structureInfo.PNext = null;
                _structureInfo.AccelerationStructureCount = 1;
                var accelerationStructurePinned = accelerationStructure.VkAccelerationStructure;
                _structureInfo.PAccelerationStructures = (AccelerationStructureKHR *)Unsafe.AsPointer(ref accelerationStructurePinned);

                // Accumulation image
                var _accumulationImageInfo = new DescriptorImageInfo();
                _accumulationImageInfo.ImageView   = accumulationImageView.VkImageView;
                _accumulationImageInfo.ImageLayout = ImageLayout.General;

                // Output image
                var _outputImageInfo = new DescriptorImageInfo();
                _outputImageInfo.ImageView   = outputImageView.VkImageView;
                _outputImageInfo.ImageLayout = ImageLayout.General;

                // Uniform buffer
                var _uniformBufferInfo = new DescriptorBufferInfo();
                _uniformBufferInfo.Buffer = uniformBuffers[i].Buffer.VkBuffer;
                _uniformBufferInfo.Range  = Vk.WholeSize;

                // Vertex buffer
                var _vertexBufferInfo = new DescriptorBufferInfo();
                _vertexBufferInfo.Buffer = scene.VertexBuffer.VkBuffer;
                _vertexBufferInfo.Range  = Vk.WholeSize;

                // Index buffer
                var _indexBufferInfo = new DescriptorBufferInfo();
                _indexBufferInfo.Buffer = scene.IndexBuffer.VkBuffer;
                _indexBufferInfo.Range  = Vk.WholeSize;

                // Material buffer
                var _materialBufferInfo = new DescriptorBufferInfo();
                _materialBufferInfo.Buffer = scene.MaterialBuffer.VkBuffer;
                _materialBufferInfo.Range  = Vk.WholeSize;

                // Offsets buffer
                var _offsetsBufferInfo = new DescriptorBufferInfo();
                _offsetsBufferInfo.Buffer = scene.OffsetsBuffer.VkBuffer;
                _offsetsBufferInfo.Range  = Vk.WholeSize;

                // Transforms buffer
                var _transformsBufferInfo = new DescriptorBufferInfo();
                _transformsBufferInfo.Buffer = scene.TransformsBuffer.VkBuffer;
                _transformsBufferInfo.Range  = Vk.WholeSize;

                // Image and texture samplers.
                var imageInfos = GC.AllocateArray <DescriptorImageInfo>(scene.TextureSamplers.Count, true);

                for (int t = 0; t != imageInfos.Length; ++t)
                {
                    var imageInfo = imageInfos[t];
                    imageInfo.ImageLayout = ImageLayout.ShaderReadOnlyOptimal;
                    imageInfo.ImageView   = scene.TextureImageViews[t];
                    imageInfo.Sampler     = scene.TextureSamplers[t];
                    imageInfos[t]         = imageInfo;
                }

                int descriptorWriteCt = scene.HasProcedurals ? 11 : 10;
#pragma warning disable CA2014 // Do not use stackalloc in loops
                Span <WriteDescriptorSet> descriptorWrites = stackalloc WriteDescriptorSet[descriptorWriteCt];
#pragma warning restore CA2014 // Do not use stackalloc in loops

                descriptorSets.Bind(i, 0, (WriteDescriptorSetAccelerationStructureKHR *)Unsafe.AsPointer(ref _structureInfo), out descriptorWrites[0]);
                descriptorSets.Bind(i, 1, (DescriptorImageInfo *)Unsafe.AsPointer(ref _accumulationImageInfo), out descriptorWrites[1]);
                descriptorSets.Bind(i, 2, (DescriptorImageInfo *)Unsafe.AsPointer(ref _outputImageInfo), out descriptorWrites[2]);
                descriptorSets.Bind(i, 3, (DescriptorBufferInfo *)Unsafe.AsPointer(ref _uniformBufferInfo), out descriptorWrites[3]);
                descriptorSets.Bind(i, 4, (DescriptorBufferInfo *)Unsafe.AsPointer(ref _vertexBufferInfo), out descriptorWrites[4]);
                descriptorSets.Bind(i, 5, (DescriptorBufferInfo *)Unsafe.AsPointer(ref _indexBufferInfo), out descriptorWrites[5]);
                descriptorSets.Bind(i, 6, (DescriptorBufferInfo *)Unsafe.AsPointer(ref _materialBufferInfo), out descriptorWrites[6]);
                descriptorSets.Bind(i, 7, (DescriptorBufferInfo *)Unsafe.AsPointer(ref _offsetsBufferInfo), out descriptorWrites[7]);
                descriptorSets.Bind(i, 8, (DescriptorBufferInfo *)Unsafe.AsPointer(ref _transformsBufferInfo), out descriptorWrites[8]);
                descriptorSets.Bind(i, 9, (DescriptorImageInfo *)Unsafe.AsPointer(ref imageInfos[0]), out descriptorWrites[9], (uint)imageInfos.Length);

                // Procedural buffer (optional)
                var _proceduralBufferInfo = new DescriptorBufferInfo();
                _proceduralBufferInfo.Buffer = scene.ProceduralBuffer.VkBuffer;
                _proceduralBufferInfo.Range  = Vk.WholeSize;

                if (scene.HasProcedurals)
                {
                    descriptorSets.Bind(i, 10, (DescriptorBufferInfo *)Unsafe.AsPointer(ref _proceduralBufferInfo), out descriptorWrites[10]);
                }

                descriptorSets.UpdateDescriptors(descriptorWrites);
            }

            _pipelineLayout = new PipelineLayout(_api, _descriptorSetManager.DescriptorSetLayout);

            // Load shaders.
            var rayGenShader                 = new ShaderModule(_api, "./assets/shaders/RayTracing.rgen.spv");
            var missShader                   = new ShaderModule(_api, "./assets/shaders/RayTracing.rmiss.spv");
            var closestHitShader             = new ShaderModule(_api, "./assets/shaders/RayTracing.rchit.spv");
            var proceduralClosestHitShader   = new ShaderModule(_api, "./assets/shaders/RayTracing.Procedural.rchit.spv");
            var proceduralIntersectionShader = new ShaderModule(_api, "./assets/shaders/RayTracing.Procedural.rint.spv");

            Span <PipelineShaderStageCreateInfo> shaderStages = stackalloc PipelineShaderStageCreateInfo[]
            {
                rayGenShader.CreateShaderStage(ShaderStageFlags.ShaderStageRaygenBitKhr),
                missShader.CreateShaderStage(ShaderStageFlags.ShaderStageMissBitKhr),
                closestHitShader.CreateShaderStage(ShaderStageFlags.ShaderStageClosestHitBitKhr),
                proceduralClosestHitShader.CreateShaderStage(ShaderStageFlags.ShaderStageClosestHitBitKhr),
                proceduralIntersectionShader.CreateShaderStage(ShaderStageFlags.ShaderStageIntersectionBitKhr)
            };

            const uint VK_SHADER_UNUSED_KHR = (~0U);

            // Shader groups
            var rayGenGroupInfo = new RayTracingShaderGroupCreateInfoKHR();
            rayGenGroupInfo.SType              = StructureType.RayTracingShaderGroupCreateInfoKhr;
            rayGenGroupInfo.PNext              = null;
            rayGenGroupInfo.Type               = RayTracingShaderGroupTypeKHR.RayTracingShaderGroupTypeGeneralKhr;
            rayGenGroupInfo.GeneralShader      = 0;
            rayGenGroupInfo.ClosestHitShader   = VK_SHADER_UNUSED_KHR;
            rayGenGroupInfo.AnyHitShader       = VK_SHADER_UNUSED_KHR;
            rayGenGroupInfo.IntersectionShader = VK_SHADER_UNUSED_KHR;
            _rayGenIndex = 0;

            var missGroupInfo = new RayTracingShaderGroupCreateInfoKHR();
            missGroupInfo.SType              = StructureType.RayTracingShaderGroupCreateInfoKhr;
            missGroupInfo.PNext              = null;
            missGroupInfo.Type               = RayTracingShaderGroupTypeKHR.RayTracingShaderGroupTypeGeneralKhr;
            missGroupInfo.GeneralShader      = 1;
            missGroupInfo.ClosestHitShader   = VK_SHADER_UNUSED_KHR;
            missGroupInfo.AnyHitShader       = VK_SHADER_UNUSED_KHR;
            missGroupInfo.IntersectionShader = VK_SHADER_UNUSED_KHR;
            _missIndex = 1;

            var triangleHitGroupInfo = new RayTracingShaderGroupCreateInfoKHR();
            triangleHitGroupInfo.SType              = StructureType.RayTracingShaderGroupCreateInfoKhr;
            triangleHitGroupInfo.PNext              = null;
            triangleHitGroupInfo.Type               = RayTracingShaderGroupTypeKHR.RayTracingShaderGroupTypeTrianglesHitGroupKhr;
            triangleHitGroupInfo.GeneralShader      = VK_SHADER_UNUSED_KHR;
            triangleHitGroupInfo.ClosestHitShader   = 2;
            triangleHitGroupInfo.AnyHitShader       = VK_SHADER_UNUSED_KHR;
            triangleHitGroupInfo.IntersectionShader = VK_SHADER_UNUSED_KHR;
            _triangleHitGroupIndex = 2;

            var proceduralHitGroupInfo = new RayTracingShaderGroupCreateInfoKHR();
            proceduralHitGroupInfo.SType              = StructureType.RayTracingShaderGroupCreateInfoKhr;
            proceduralHitGroupInfo.PNext              = null;
            proceduralHitGroupInfo.Type               = RayTracingShaderGroupTypeKHR.RayTracingShaderGroupTypeProceduralHitGroupKhr;
            proceduralHitGroupInfo.GeneralShader      = VK_SHADER_UNUSED_KHR;
            proceduralHitGroupInfo.ClosestHitShader   = 3;
            proceduralHitGroupInfo.AnyHitShader       = VK_SHADER_UNUSED_KHR;
            proceduralHitGroupInfo.IntersectionShader = 4;
            _proceduralHitGroupIndex = 3;

            Span <RayTracingShaderGroupCreateInfoKHR> groups = stackalloc RayTracingShaderGroupCreateInfoKHR[]
            {
                rayGenGroupInfo,
                missGroupInfo,
                triangleHitGroupInfo,
                proceduralHitGroupInfo,
            };

            // Create graphic pipeline
            var pipelineInfo = new RayTracingPipelineCreateInfoKHR();
            pipelineInfo.SType      = StructureType.RayTracingPipelineCreateInfoKhr;
            pipelineInfo.PNext      = null;
            pipelineInfo.Flags      = 0;
            pipelineInfo.StageCount = (uint)shaderStages.Length;
            pipelineInfo.PStages    = (PipelineShaderStageCreateInfo *)Unsafe.AsPointer(ref shaderStages[0]);
            pipelineInfo.GroupCount = (uint)groups.Length;
            pipelineInfo.PGroups    = (RayTracingShaderGroupCreateInfoKHR *)Unsafe.AsPointer(ref groups[0]);
            pipelineInfo.MaxPipelineRayRecursionDepth = 1;
            pipelineInfo.Layout             = _pipelineLayout.VkPipelineLayout;
            pipelineInfo.BasePipelineHandle = default;
            pipelineInfo.BasePipelineIndex  = 0;

            Util.Verify(
                _api.KhrRayTracingPipeline.CreateRayTracingPipelines(_api.Device.VkDevice, default, default, 1, pipelineInfo, default, out _pipeline),
Ejemplo n.º 20
0
        public unsafe void SetUniforms(Frame frame, DescriptorSet descriptorSet, ulong uniformOffset, int image)
        {
            DescriptorBufferInfo vertexUniformBufferInfo = frame.VertexUniformBuffer.BufferInfo;

            vertexUniformBufferInfo.Offset = 0;
            DescriptorBufferInfo fragmentUniformBufferInfo = frame.FragmentUniformBuffer.BufferInfo;

            fragmentUniformBufferInfo.Offset = uniformOffset;
            fragmentUniformBufferInfo.Range  = (uint)Marshal.SizeOf <FragUniforms>();

            int id = _renderer.DummyTex;

            if (image != 0)
            {
                id = image;
            }
            DescriptorImageInfo fragmentImageInfo = _renderer.TextureManager.FindTexture(id).ImageInfo;

            Span <WriteDescriptorSet> descriptorWrites = stackalloc WriteDescriptorSet[]
            {
                new WriteDescriptorSet() // Vertex Uniform Buffer
                {
                    SType = StructureType.WriteDescriptorSet,

                    DstBinding      = 0,
                    DstArrayElement = 0,
                    DstSet          = descriptorSet,

                    DescriptorCount = 1,
                    DescriptorType  = DescriptorType.UniformBuffer,
                    PBufferInfo     = &vertexUniformBufferInfo
                },
                new WriteDescriptorSet() // Fragment Uniform Buffer
                {
                    SType = StructureType.WriteDescriptorSet,

                    DstBinding      = 1,
                    DstArrayElement = 0,
                    DstSet          = descriptorSet,

                    DescriptorCount = 1,
                    DescriptorType  = DescriptorType.UniformBuffer,
                    PBufferInfo     = &fragmentUniformBufferInfo
                },
                new WriteDescriptorSet() // Fragment Image Sampler(2D)
                {
                    SType = StructureType.WriteDescriptorSet,

                    DstBinding      = 2,
                    DstArrayElement = 0,
                    DstSet          = descriptorSet,

                    DescriptorCount = 1,
                    DescriptorType  = DescriptorType.CombinedImageSampler,
                    PImageInfo      = &fragmentImageInfo
                }
            };

            Device device = _renderer.Params.Device;
            Vk     vk     = _renderer.Vk;

            vk.UpdateDescriptorSets(device, (uint)descriptorWrites.Length, in descriptorWrites[0], 0, null);
        }