Esempio n. 1
0
        private unsafe CommandBuffer BeginImageCommandBuffer()
        {
            Device device = _renderer.Params.Device;
            Vk     vk     = _renderer.Vk;

            CommandBufferAllocateInfo commandBufferAllocateInfo = new()
            {
                SType = StructureType.CommandBufferAllocateInfo,

                CommandBufferCount = 1,
                CommandPool        = _renderer.ImageTransitionPool
            };

            _renderer.AssertVulkan(vk.AllocateCommandBuffers(device, commandBufferAllocateInfo, out CommandBuffer commandBuffer));

            CommandBufferBeginInfo commandBufferBeginInfo = new()
            {
                SType = StructureType.CommandBufferBeginInfo,
                Flags = CommandBufferUsageFlags.CommandBufferUsageOneTimeSubmitBit,

                PInheritanceInfo = null
            };

            _renderer.AssertVulkan(vk.BeginCommandBuffer(commandBuffer, commandBufferBeginInfo));

            return(commandBuffer);
        }

        private unsafe void EndImageCommandBuffer(CommandBuffer commandBuffer)
        {
            Device device = _renderer.Params.Device;
            Vk     vk     = _renderer.Vk;

            _renderer.AssertVulkan(vk.EndCommandBuffer(commandBuffer));

            SubmitInfo submitInfo = new()
            {
                SType = StructureType.SubmitInfo,

                CommandBufferCount = 1,
                PCommandBuffers    = &commandBuffer,

                SignalSemaphoreCount = 0,
                PSignalSemaphores    = null,
                WaitSemaphoreCount   = 0,
                PWaitSemaphores      = null,
                PWaitDstStageMask    = null
            };

            _renderer.AssertVulkan(vk.QueueSubmit(_renderer.ImageTransitionQueue, 1, submitInfo, default));
            _renderer.AssertVulkan(vk.QueueWaitIdle(_renderer.ImageTransitionQueue));

            vk.FreeCommandBuffers(device, _renderer.ImageTransitionPool, 1, commandBuffer);
        }

        private unsafe void TransitionImageLayout(ImageLayout oldLayout, ImageLayout newLayout)
        {
            Vk vk = _renderer.Vk;

            CommandBuffer commandBuffer = BeginImageCommandBuffer();

            ImageMemoryBarrier imageMemoryBarrier = new()
            {
                SType = StructureType.ImageMemoryBarrier,

                OldLayout = oldLayout,
                NewLayout = newLayout,

                SrcQueueFamilyIndex = Vk.QueueFamilyIgnored,
                DstQueueFamilyIndex = Vk.QueueFamilyIgnored,

                Image = _image,

                SubresourceRange = new ImageSubresourceRange()
                {
                    AspectMask     = ImageAspectFlags.ImageAspectColorBit,
                    BaseArrayLayer = 0,
                    LayerCount     = 1,
                    BaseMipLevel   = 0,
                    LevelCount     = _mipLevelCount
                },

                SrcAccessMask = 0,
                DstAccessMask = 0
            };

            if ((oldLayout == ImageLayout.Undefined) && (newLayout == ImageLayout.TransferDstOptimal))
            {
                imageMemoryBarrier.SrcAccessMask = 0;
                imageMemoryBarrier.DstAccessMask = AccessFlags.AccessTransferWriteBit;

                vk.CmdPipelineBarrier(commandBuffer, PipelineStageFlags.PipelineStageTopOfPipeBit, PipelineStageFlags.PipelineStageTransferBit, 0, 0, null, 0, null, 1, imageMemoryBarrier);
            }
            else if ((oldLayout == ImageLayout.TransferDstOptimal) && (newLayout == ImageLayout.ShaderReadOnlyOptimal))
            {
                imageMemoryBarrier.SrcAccessMask = AccessFlags.AccessTransferWriteBit;
                imageMemoryBarrier.DstAccessMask = AccessFlags.AccessShaderReadBit;

                vk.CmdPipelineBarrier(commandBuffer, PipelineStageFlags.PipelineStageTransferBit, PipelineStageFlags.PipelineStageFragmentShaderBit, 0, 0, null, 0, null, 1, imageMemoryBarrier);
            }
            else if ((oldLayout == ImageLayout.ShaderReadOnlyOptimal) && (newLayout == ImageLayout.TransferDstOptimal))
            {
                imageMemoryBarrier.SrcAccessMask = AccessFlags.AccessShaderReadBit;
                imageMemoryBarrier.DstAccessMask = AccessFlags.AccessTransferWriteBit;

                vk.CmdPipelineBarrier(commandBuffer, PipelineStageFlags.PipelineStageFragmentShaderBit, PipelineStageFlags.PipelineStageTransferBit, 0, 0, null, 0, null, 1, imageMemoryBarrier);
            }

            EndImageCommandBuffer(commandBuffer);
        }

        private void CopyBufferToImage(Buffer <byte> source)
        {
            Vk vk = _renderer.Vk;

            CommandBuffer commandBuffer = BeginImageCommandBuffer();

            BufferImageCopy bufferImageCopy = new()
            {
                BufferOffset      = 0,
                BufferRowLength   = 0,
                BufferImageHeight = 0,

                ImageSubresource = new ImageSubresourceLayers()
                {
                    AspectMask     = ImageAspectFlags.ImageAspectColorBit,
                    MipLevel       = 0,
                    BaseArrayLayer = 0,
                    LayerCount     = 1
                },

                ImageOffset = new Offset3D()
                {
                    X = 0,
                    Y = 0,
                    Z = 0
                },
                ImageExtent = new Extent3D()
                {
                    Width  = Size.X,
                    Height = Size.Y,
                    Depth  = 1
                }
            };

            vk.CmdCopyBufferToImage(commandBuffer, source.Handle, _image, ImageLayout.TransferDstOptimal, 1, bufferImageCopy);

            EndImageCommandBuffer(commandBuffer);
        }
Esempio n. 2
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();
        }