Beispiel #1
0
 public BufferManager(VulkanGraphicsDevice gd, PhysicalDevice physicalDevice, Device device)
 {
     _physicalDevice = physicalDevice;
     _device         = device;
     _buffers        = new List <BufferHolder>();
     StagingBuffer   = new StagingBuffer(gd, this);
 }
Beispiel #2
0
        public unsafe BufferHolder Create(VulkanGraphicsDevice gd, int size, bool forConditionalRendering = false)
        {
            var usage = DefaultBufferUsageFlags;

            if (forConditionalRendering && gd.Capabilities.SupportsConditionalRendering)
            {
                usage |= BufferUsageFlags.BufferUsageConditionalRenderingBitExt;
            }

            var bufferCreateInfo = new BufferCreateInfo()
            {
                SType       = StructureType.BufferCreateInfo,
                Size        = (ulong)size,
                Usage       = usage,
                SharingMode = SharingMode.Exclusive
            };

            gd.Api.CreateBuffer(_device, in bufferCreateInfo, null, out var buffer).ThrowOnError();
            gd.Api.GetBufferMemoryRequirements(_device, buffer, out var requirements);
            var allocation = gd.MemoryAllocator.AllocateDeviceMemory(_physicalDevice, requirements, DefaultBufferMemoryFlags);

            if (allocation.Memory.Handle == 0UL)
            {
                gd.Api.DestroyBuffer(_device, buffer, null);
                return(null);
            }

            gd.Api.BindBufferMemory(_device, buffer, allocation.Memory, allocation.Offset);

            return(new BufferHolder(gd, _device, buffer, allocation, size));
        }
Beispiel #3
0
 public StagingBuffer(VulkanGraphicsDevice gd, BufferManager bufferManager)
 {
     _gd            = gd;
     _buffer        = bufferManager.Create(gd, BufferSize);
     _pendingCopies = new Queue <PendingCopy>();
     _freeSize      = BufferSize;
 }
Beispiel #4
0
        public static unsafe void InsertBufferBarrier(
            VulkanGraphicsDevice gd,
            CommandBuffer commandBuffer,
            VkBuffer buffer,
            AccessFlags srcAccessMask,
            AccessFlags dstAccessMask,
            PipelineStageFlags srcStageMask,
            PipelineStageFlags dstStageMask,
            int offset,
            int size)
        {
            BufferMemoryBarrier memoryBarrier = new BufferMemoryBarrier()
            {
                SType               = StructureType.BufferMemoryBarrier,
                SrcAccessMask       = srcAccessMask,
                DstAccessMask       = dstAccessMask,
                SrcQueueFamilyIndex = Vk.QueueFamilyIgnored,
                DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
                Buffer              = buffer,
                Offset              = (ulong)offset,
                Size = (ulong)size
            };

            gd.Api.CmdPipelineBarrier(
                commandBuffer,
                srcStageMask,
                dstStageMask,
                0,
                0,
                null,
                1,
                memoryBarrier,
                0,
                null);
        }
        public PipelineLayoutCacheEntry(VulkanGraphicsDevice gd, Device device, uint stages)
        {
            _gd     = gd;
            _device = device;
            _stages = stages;

            DescriptorSetLayouts = PipelineLayoutFactory.Create(gd, device, stages, out var pipelineLayout);
            PipelineLayout       = pipelineLayout;

            DescriptorSetCache = new DescriptorSetCache(gd, DescriptorSetLayouts);

            _dsCache = new List <Auto <DescriptorSetCollection> > [CommandBufferPool.MaxCommandBuffers][];

            for (int i = 0; i < CommandBufferPool.MaxCommandBuffers; i++)
            {
                _dsCache[i] = new List <Auto <DescriptorSetCollection> > [PipelineBase.DescriptorSetLayouts];

                for (int j = 0; j < PipelineBase.DescriptorSetLayouts; j++)
                {
                    _dsCache[i][j] = new List <Auto <DescriptorSetCollection> >();
                }
            }

            _dsCacheCursor = new int[PipelineBase.DescriptorSetLayouts];
        }
Beispiel #6
0
        public unsafe PipelineBase(VulkanGraphicsDevice gd, Device device)
        {
            Gd     = gd;
            Device = device;

            var pipelineCacheCreateInfo = new PipelineCacheCreateInfo()
            {
                SType = StructureType.PipelineCacheCreateInfo
            };

            gd.Api.CreatePipelineCache(device, pipelineCacheCreateInfo, null, out _pipelineCache).ThrowOnError();

            _descriptorSetUpdater = new DescriptorSetUpdater(gd, this);

            _transformFeedbackBuffers = new BufferState[Constants.MaxTransformFeedbackBuffers];
            _vertexBuffers            = new BufferState[Constants.MaxVertexBuffers + 1];

            const int EmptyVbSize = 16;

            using var emptyVb = gd.BufferManager.Create(gd, EmptyVbSize);
            emptyVb.SetData(0, new byte[EmptyVbSize]);
            _vertexBuffers[0]         = new BufferState(emptyVb.GetBuffer(), 0, EmptyVbSize, 0UL);
            _needsVertexBuffersRebind = true;

            RenderScaleBuffer = gd.BufferManager.Create(gd, SupportBuffer.RequiredSize);

            _newState.Initialize();
            _newState.LineWidth = 1f;
        }
        public Auto <DescriptorSetCollection> GetNewDescriptorSetCollection(
            VulkanGraphicsDevice gd,
            int commandBufferIndex,
            int setIndex,
            out bool isNew)
        {
            if (_dsLastCbIndex != commandBufferIndex)
            {
                _dsLastCbIndex = commandBufferIndex;

                for (int i = 0; i < PipelineBase.DescriptorSetLayouts; i++)
                {
                    _dsCacheCursor[i] = 0;
                }
            }

            var list  = _dsCache[commandBufferIndex][setIndex];
            int index = _dsCacheCursor[setIndex]++;

            if (index == list.Count)
            {
                var dsc = gd.DescriptorSetManager.AllocateDescriptorSet(gd.Api, DescriptorSetLayouts[setIndex]);
                list.Add(dsc);
                isNew = true;
                return(dsc);
            }

            isNew = false;
            return(list[index]);
        }
Beispiel #8
0
 public Auto <DescriptorSetCollection> GetNewDescriptorSetCollection(
     VulkanGraphicsDevice gd,
     int commandBufferIndex,
     int setIndex,
     out bool isNew)
 {
     return(_plce.GetNewDescriptorSetCollection(gd, commandBufferIndex, setIndex, out isNew));
 }
Beispiel #9
0
        protected override unsafe DescriptorSetLayout[] CreateDescriptorSetLayouts(VulkanGraphicsDevice gd, Device device, out PipelineLayout layout)
        {
            DescriptorSetLayoutBinding uLayoutBindings = new DescriptorSetLayoutBinding
            {
                Binding         = 0,
                DescriptorType  = DescriptorType.UniformBuffer,
                DescriptorCount = 1,
                StageFlags      = ShaderStageFlags.ShaderStageVertexBit
            };

            DescriptorSetLayoutBinding tLayoutBindings = new DescriptorSetLayoutBinding
            {
                Binding         = 0,
                DescriptorType  = DescriptorType.CombinedImageSampler,
                DescriptorCount = 1,
                StageFlags      = ShaderStageFlags.ShaderStageFragmentBit
            };

            DescriptorSetLayout[] layouts = new DescriptorSetLayout[3];

            var uDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = &uLayoutBindings,
                BindingCount = 1
            };

            var sDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                BindingCount = 0
            };

            var tDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = &tLayoutBindings,
                BindingCount = 1
            };

            gd.Api.CreateDescriptorSetLayout(device, uDescriptorSetLayoutCreateInfo, null, out layouts[0]).ThrowOnError();
            gd.Api.CreateDescriptorSetLayout(device, sDescriptorSetLayoutCreateInfo, null, out layouts[1]).ThrowOnError();
            gd.Api.CreateDescriptorSetLayout(device, tDescriptorSetLayoutCreateInfo, null, out layouts[2]).ThrowOnError();

            fixed(DescriptorSetLayout *pLayouts = layouts)
            {
                var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo()
                {
                    SType          = StructureType.PipelineLayoutCreateInfo,
                    PSetLayouts    = pLayouts,
                    SetLayoutCount = 3
                };

                gd.Api.CreatePipelineLayout(device, &pipelineLayoutCreateInfo, null, out layout).ThrowOnError();
            }

            return(layouts);
        }
Beispiel #10
0
        public PipelineLayoutCacheEntry GetOrCreate(VulkanGraphicsDevice gd, Device device, uint stages)
        {
            if (_plce[stages] == null)
            {
                _plce[stages] = new PipelineLayoutCacheEntry(gd, device, stages);
            }

            return(_plce[stages]);
        }
Beispiel #11
0
        public void BindVertexBuffer(VulkanGraphicsDevice gd, CommandBufferScoped cbs, uint binding)
        {
            if (_buffer != null)
            {
                var buffer = _buffer.Get(cbs, _offset, _size).Value;

                gd.Api.CmdBindVertexBuffers(cbs.CommandBuffer, binding, 1, buffer, (ulong)_offset);
            }
        }
Beispiel #12
0
        public TextureBuffer(VulkanGraphicsDevice gd, TextureCreateInfo info, float scale)
        {
            _gd         = gd;
            Width       = info.Width;
            Height      = info.Height;
            VkFormat    = FormatTable.GetFormat(info.Format);
            ScaleFactor = scale;

            gd.Textures.Add(this);
        }
Beispiel #13
0
 public DescriptorSetCache(VulkanGraphicsDevice gd, DescriptorSetLayout[] descriptorSetLayouts)
 {
     _gd = gd;
     _descriptorSetLayouts = descriptorSetLayouts;
     _uCache  = new Dictionary <BufferHandleSet, DescriptorSetCollection>();
     _sCache  = new Dictionary <BufferHandleSet, DescriptorSetCollection>();
     _tCache  = new Dictionary <CombinedImageHandleSet, DescriptorSetCollection>();
     _iCache  = new Dictionary <HandleSet, DescriptorSetCollection>();
     _bTCache = new Dictionary <HandleSet, DescriptorSetCollection>();
     _bICache = new Dictionary <HandleSet, DescriptorSetCollection>();
 }
Beispiel #14
0
 public BufferHolder(VulkanGraphicsDevice gd, Device device, VkBuffer buffer, MemoryAllocation allocation, int size)
 {
     _gd             = gd;
     _device         = device;
     _allocation     = allocation;
     _allocationAuto = new Auto <MemoryAllocation>(allocation);
     _waitable       = new MultiFenceHolder();
     _buffer         = new Auto <DisposableBuffer>(new DisposableBuffer(gd.Api, device, buffer), _waitable, _allocationAuto);
     _bufferHandle   = buffer.Handle;
     Size            = size;
     _map            = allocation.HostPointer;
 }
Beispiel #15
0
        public unsafe SamplerHolder(VulkanGraphicsDevice gd, Device device, GAL.SamplerCreateInfo info)
        {
            _gd = gd;

            gd.Samplers.Add(this);

            (Filter minFilter, SamplerMipmapMode mipFilter) = EnumConversion.Convert(info.MinFilter);

            var borderColor = GetConstrainedBorderColor(info.BorderColor, out var cantConstrain);

            var samplerCreateInfo = new Silk.NET.Vulkan.SamplerCreateInfo()
            {
                SType                   = StructureType.SamplerCreateInfo,
                MagFilter               = info.MagFilter.Convert(),
                MinFilter               = minFilter,
                MipmapMode              = mipFilter,
                AddressModeU            = info.AddressU.Convert(),
                AddressModeV            = info.AddressV.Convert(),
                AddressModeW            = info.AddressP.Convert(),
                MipLodBias              = info.MipLodBias,
                AnisotropyEnable        = info.MaxAnisotropy != 1f,
                MaxAnisotropy           = info.MaxAnisotropy,
                CompareEnable           = info.CompareMode == CompareMode.CompareRToTexture,
                CompareOp               = info.CompareOp.Convert(),
                MinLod                  = info.MinLod,
                MaxLod                  = info.MaxLod,
                BorderColor             = borderColor,
                UnnormalizedCoordinates = false // TODO: Use unnormalized coordinates.
            };

            SamplerCustomBorderColorCreateInfoEXT customBorderColor;

            if (cantConstrain && gd.SupportsCustomBorderColor)
            {
                var color = new ClearColorValue(
                    info.BorderColor.Red,
                    info.BorderColor.Green,
                    info.BorderColor.Blue,
                    info.BorderColor.Alpha);

                customBorderColor = new SamplerCustomBorderColorCreateInfoEXT()
                {
                    SType             = StructureType.SamplerCustomBorderColorCreateInfoExt,
                    CustomBorderColor = color
                };

                samplerCreateInfo.PNext = &customBorderColor;
            }

            gd.Api.CreateSampler(device, samplerCreateInfo, null, out var sampler).ThrowOnError();

            _sampler = new Auto <DisposableSampler>(new DisposableSampler(gd.Api, device, sampler));
        }
Beispiel #16
0
        protected override unsafe DescriptorSetLayout[] CreateDescriptorSetLayouts(VulkanGraphicsDevice gd, Device device, out PipelineLayout layout)
        {
            DescriptorSetLayoutBinding *uLayoutBindings  = stackalloc DescriptorSetLayoutBinding[Constants.MaxUniformBufferBindings];
            DescriptorSetLayoutBinding *sLayoutBindings  = stackalloc DescriptorSetLayoutBinding[Constants.MaxStorageBufferBindings];
            DescriptorSetLayoutBinding *tLayoutBindings  = stackalloc DescriptorSetLayoutBinding[Constants.MaxTextureBindings];
            DescriptorSetLayoutBinding *iLayoutBindings  = stackalloc DescriptorSetLayoutBinding[Constants.MaxImageBindings];
            DescriptorSetLayoutBinding *bTLayoutBindings = stackalloc DescriptorSetLayoutBinding[Constants.MaxTextureBindings];
            DescriptorSetLayoutBinding *bILayoutBindings = stackalloc DescriptorSetLayoutBinding[Constants.MaxImageBindings];

            DescriptorBindingFlags *pUBindingsFlags  = stackalloc DescriptorBindingFlags[Constants.MaxUniformBufferBindings];
            DescriptorBindingFlags *pSBindingsFlags  = stackalloc DescriptorBindingFlags[Constants.MaxStorageBufferBindings];
            DescriptorBindingFlags *pTBindingsFlags  = stackalloc DescriptorBindingFlags[Constants.MaxTextureBindings];
            DescriptorBindingFlags *pIBindingsFlags  = stackalloc DescriptorBindingFlags[Constants.MaxImageBindings];
            DescriptorBindingFlags *pBTBindingsFlags = stackalloc DescriptorBindingFlags[Constants.MaxTextureBindings];
            DescriptorBindingFlags *pBIBindingsFlags = stackalloc DescriptorBindingFlags[Constants.MaxImageBindings];
Beispiel #17
0
        public BufferHandle CreateWithHandle(VulkanGraphicsDevice gd, int size)
        {
            var holder = Create(gd, size);

            if (holder == null)
            {
                return(BufferHandle.Null);
            }

            ulong handle64 = (ulong)_buffers.Count + 1;

            var handle = Unsafe.As <ulong, BufferHandle>(ref handle64);

            _buffers.Add(holder);

            return(handle);
        }
Beispiel #18
0
        public unsafe Window(VulkanGraphicsDevice gd, SurfaceKHR surface, PhysicalDevice physicalDevice, Device device)
        {
            _gd             = gd;
            _physicalDevice = physicalDevice;
            _device         = device;
            _surface        = surface;

            CreateSwapchain();

            var semaphoreCreateInfo = new SemaphoreCreateInfo()
            {
                SType = StructureType.SemaphoreCreateInfo
            };

            gd.Api.CreateSemaphore(device, semaphoreCreateInfo, null, out _imageAvailableSemaphore).ThrowOnError();
            gd.Api.CreateSemaphore(device, semaphoreCreateInfo, null, out _renderFinishedSemaphore).ThrowOnError();
        }
        public DescriptorSetUpdater(VulkanGraphicsDevice gd, PipelineBase pipeline)
        {
            _gd       = gd;
            _pipeline = pipeline;

            _uniformBuffers = Array.Empty <DescriptorBufferInfo>();
            _storageBuffers = Array.Empty <DescriptorBufferInfo>();
            _textures       = new DescriptorImageInfo[32 * 5];
            _textureRefs    = new Auto <DisposableImageView> [32 * 5];
            _samplerRefs    = new Auto <DisposableSampler> [32 * 5];
            _images         = Array.Empty <DescriptorImageInfo>();
            _bufferTextures = Array.Empty <BufferView>();
            _bufferImages   = Array.Empty <BufferView>();

            _dummyTexture = (TextureView)gd.CreateTexture(new GAL.TextureCreateInfo(
                                                              1,
                                                              1,
                                                              1,
                                                              1,
                                                              1,
                                                              1,
                                                              1,
                                                              4,
                                                              GAL.Format.R8G8B8A8Unorm,
                                                              DepthStencilMode.Depth,
                                                              Target.Texture2D,
                                                              SwizzleComponent.Red,
                                                              SwizzleComponent.Green,
                                                              SwizzleComponent.Blue,
                                                              SwizzleComponent.Alpha), 1f);

            _dummySampler = (SamplerHolder)gd.CreateSampler(new GAL.SamplerCreateInfo(
                                                                MinFilter.Nearest,
                                                                MagFilter.Nearest,
                                                                false,
                                                                AddressMode.Repeat,
                                                                AddressMode.Repeat,
                                                                AddressMode.Repeat,
                                                                CompareMode.None,
                                                                GAL.CompareOp.Always,
                                                                new ColorF(0, 0, 0, 0),
                                                                0,
                                                                0,
                                                                0,
                                                                1f));
        }
Beispiel #20
0
        public static unsafe void Copy(
            VulkanGraphicsDevice gd,
            CommandBufferScoped cbs,
            Auto <DisposableBuffer> src,
            Auto <DisposableBuffer> dst,
            int srcOffset,
            int dstOffset,
            int size)
        {
            var srcBuffer = src.Get(cbs, srcOffset, size).Value;
            var dstBuffer = dst.Get(cbs, dstOffset, size).Value;

            InsertBufferBarrier(
                gd,
                cbs.CommandBuffer,
                dstBuffer,
                BufferHolder.DefaultAccessFlags,
                AccessFlags.AccessTransferWriteBit,
                PipelineStageFlags.PipelineStageAllCommandsBit,
                PipelineStageFlags.PipelineStageTransferBit,
                dstOffset,
                size);

            var region = new BufferCopy((ulong)srcOffset, (ulong)dstOffset, (ulong)size);

            gd.Api.CmdCopyBuffer(cbs.CommandBuffer, srcBuffer, dstBuffer, 1, &region);

            InsertBufferBarrier(
                gd,
                cbs.CommandBuffer,
                dstBuffer,
                AccessFlags.AccessTransferWriteBit,
                BufferHolder.DefaultAccessFlags,
                PipelineStageFlags.PipelineStageTransferBit,
                PipelineStageFlags.PipelineStageAllCommandsBit,
                dstOffset,
                size);
        }
Beispiel #21
0
        public unsafe TextureStorage(
            VulkanGraphicsDevice gd,
            PhysicalDevice physicalDevice,
            Device device,
            TextureCreateInfo info,
            float scaleFactor,
            Auto <MemoryAllocation> foreignAllocation = null)
        {
            _gd         = gd;
            _device     = device;
            _info       = info;
            ScaleFactor = scaleFactor;

            var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format);
            var levels = (uint)info.Levels;
            var layers = (uint)info.GetLayers();
            var depth  = (uint)(info.Target == Target.Texture3D ? info.Depth : 1);

            VkFormat = format;

            var type = info.Target.Convert();

            var extent = new Extent3D((uint)info.Width, (uint)info.Height, depth);

            var sampleCountFlags = ConvertToSampleCountFlags((uint)info.Samples);

            var usage = DefaultUsageFlags;

            if (info.Format.IsDepthOrStencil())
            {
                usage |= ImageUsageFlags.ImageUsageDepthStencilAttachmentBit;
            }
            else if (info.Format.IsRtColorCompatible())
            {
                usage |= ImageUsageFlags.ImageUsageColorAttachmentBit;
            }

            if (info.Format.IsImageCompatible())
            {
                usage |= ImageUsageFlags.ImageUsageStorageBit;
            }

            var flags = ImageCreateFlags.ImageCreateMutableFormatBit;

            if (info.BlockWidth != 1 || info.BlockHeight != 1)
            {
                flags |= ImageCreateFlags.ImageCreateBlockTexelViewCompatibleBit;
            }

            bool cubeCompatible = info.Width == info.Height && layers >= 6;

            if (type == ImageType.ImageType2D && cubeCompatible)
            {
                flags |= ImageCreateFlags.ImageCreateCubeCompatibleBit;
            }

            if (type == ImageType.ImageType3D)
            {
                flags |= ImageCreateFlags.ImageCreate2DArrayCompatibleBit;
            }

            // System.Console.WriteLine("create image " + type + " " + format + " " + levels + " " + layers + " " + usage + " " + flags);

            var imageCreateInfo = new ImageCreateInfo()
            {
                SType         = StructureType.ImageCreateInfo,
                ImageType     = type,
                Format        = format,
                Extent        = extent,
                MipLevels     = levels,
                ArrayLayers   = layers,
                Samples       = sampleCountFlags,
                Tiling        = ImageTiling.Optimal,
                Usage         = usage,
                SharingMode   = SharingMode.Exclusive,
                InitialLayout = ImageLayout.Undefined,
                Flags         = flags
            };

            gd.Api.CreateImage(device, imageCreateInfo, null, out _image).ThrowOnError();

            if (foreignAllocation == null)
            {
                gd.Api.GetImageMemoryRequirements(device, _image, out var requirements);
                var allocation = gd.MemoryAllocator.AllocateDeviceMemory(physicalDevice, requirements);

                if (allocation.Memory.Handle == 0UL)
                {
                    gd.Api.DestroyImage(device, _image, null);
                    throw new Exception("Image initialization failed.");
                }

                gd.Api.BindImageMemory(device, _image, allocation.Memory, allocation.Offset).ThrowOnError();

                _allocationAuto = new Auto <MemoryAllocation>(allocation);
                _imageAuto      = new Auto <DisposableImage>(new DisposableImage(_gd.Api, device, _image), null, _allocationAuto);

                InitialTransition(ImageLayout.Undefined, ImageLayout.General);
            }
            else
            {
                var allocation = foreignAllocation.GetUnsafe();

                gd.Api.BindImageMemory(device, _image, allocation.Memory, allocation.Offset).ThrowOnError();

                _imageAuto = new Auto <DisposableImage>(new DisposableImage(_gd.Api, device, _image));

                InitialTransition(ImageLayout.Preinitialized, ImageLayout.General);
            }
        }
Beispiel #22
0
        public PipelineFull(VulkanGraphicsDevice gd, Device device) : base(gd, device)
        {
            _activeQueries = new List <QueryPool>();

            CommandBuffer = (Cbs = gd.CommandBufferPool.Rent()).CommandBuffer;
        }
Beispiel #23
0
 public HelperShader(VulkanGraphicsDevice gd, Device device)
 {
     _pipeline = new PipelineBlit(gd, device);
Beispiel #24
0
 public PipelineBlit(VulkanGraphicsDevice gd, Device device) : base(gd, device)
 {
 }
Beispiel #25
0
 public TextureBlit(VulkanGraphicsDevice gd, Device device)
 {
     _pipeline = new PipelineBlit(gd, device);
Beispiel #26
0
 public SyncManager(VulkanGraphicsDevice gd, Device device)
 {
     _gd      = gd;
     _device  = device;
     _handles = new List <SyncHandle>();
 }
Beispiel #27
0
        public static unsafe DescriptorSetLayout[] Create(VulkanGraphicsDevice gd, Device device, uint stages, out PipelineLayout layout)
        {
            int stagesCount = BitOperations.PopCount(stages);

            int uCount  = Constants.MaxUniformBuffersPerStage * stagesCount + 1;
            int tCount  = Constants.MaxTexturesPerStage * stagesCount;
            int iCount  = Constants.MaxImagesPerStage * stagesCount;
            int bTCount = tCount;
            int bICount = iCount;

            DescriptorSetLayoutBinding *uLayoutBindings  = stackalloc DescriptorSetLayoutBinding[uCount];
            DescriptorSetLayoutBinding *sLayoutBindings  = stackalloc DescriptorSetLayoutBinding[stagesCount];
            DescriptorSetLayoutBinding *tLayoutBindings  = stackalloc DescriptorSetLayoutBinding[tCount];
            DescriptorSetLayoutBinding *iLayoutBindings  = stackalloc DescriptorSetLayoutBinding[iCount];
            DescriptorSetLayoutBinding *bTLayoutBindings = stackalloc DescriptorSetLayoutBinding[bTCount];
            DescriptorSetLayoutBinding *bILayoutBindings = stackalloc DescriptorSetLayoutBinding[bICount];

            uLayoutBindings[0] = new DescriptorSetLayoutBinding
            {
                Binding         = 0,
                DescriptorType  = DescriptorType.UniformBuffer,
                DescriptorCount = 1,
                StageFlags      = ShaderStageFlags.ShaderStageFragmentBit | ShaderStageFlags.ShaderStageComputeBit
            };

            int iter = 0;

            while (stages != 0)
            {
                int stage = BitOperations.TrailingZeroCount(stages);
                stages &= ~(1u << stage);

                var stageFlags = stage switch
                {
                    1 => ShaderStageFlags.ShaderStageFragmentBit,
                    2 => ShaderStageFlags.ShaderStageGeometryBit,
                    3 => ShaderStageFlags.ShaderStageTessellationControlBit,
                    4 => ShaderStageFlags.ShaderStageTessellationEvaluationBit,
                    _ => ShaderStageFlags.ShaderStageVertexBit | ShaderStageFlags.ShaderStageComputeBit
                };

                void Set(DescriptorSetLayoutBinding *bindings, int maxPerStage, DescriptorType type, int start = 0)
                {
                    for (int i = 0; i < maxPerStage; i++)
                    {
                        bindings[start + iter * maxPerStage + i] = new DescriptorSetLayoutBinding
                        {
                            Binding         = (uint)(start + stage * maxPerStage + i),
                            DescriptorType  = type,
                            DescriptorCount = 1,
                            StageFlags      = stageFlags
                        };
                    }
                }

                void SetStorage(DescriptorSetLayoutBinding *bindings, int maxPerStage, int start = 0)
                {
                    bindings[start + iter] = new DescriptorSetLayoutBinding
                    {
                        Binding         = (uint)(start + stage * maxPerStage),
                        DescriptorType  = DescriptorType.StorageBuffer,
                        DescriptorCount = (uint)maxPerStage,
                        StageFlags      = stageFlags
                    };
                }

                Set(uLayoutBindings, Constants.MaxUniformBuffersPerStage, DescriptorType.UniformBuffer, 1);
                SetStorage(sLayoutBindings, Constants.MaxStorageBuffersPerStage);
                Set(tLayoutBindings, Constants.MaxTexturesPerStage, DescriptorType.CombinedImageSampler);
                Set(iLayoutBindings, Constants.MaxImagesPerStage, DescriptorType.StorageImage);
                Set(bTLayoutBindings, Constants.MaxTexturesPerStage, DescriptorType.UniformTexelBuffer);
                Set(bILayoutBindings, Constants.MaxImagesPerStage, DescriptorType.StorageTexelBuffer);

                iter++;
            }

            DescriptorSetLayout[] layouts = new DescriptorSetLayout[PipelineFull.DescriptorSetLayouts];

            var uDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = uLayoutBindings,
                BindingCount = (uint)uCount
            };

            var sDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = sLayoutBindings,
                BindingCount = (uint)stagesCount
            };

            var tDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = tLayoutBindings,
                BindingCount = (uint)tCount
            };

            var iDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = iLayoutBindings,
                BindingCount = (uint)iCount
            };

            var bTDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = bTLayoutBindings,
                BindingCount = (uint)bTCount
            };

            var bIDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = bILayoutBindings,
                BindingCount = (uint)bICount
            };

            gd.Api.CreateDescriptorSetLayout(device, uDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.UniformSetIndex]).ThrowOnError();
            gd.Api.CreateDescriptorSetLayout(device, sDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.StorageSetIndex]).ThrowOnError();
            gd.Api.CreateDescriptorSetLayout(device, tDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.TextureSetIndex]).ThrowOnError();
            gd.Api.CreateDescriptorSetLayout(device, iDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.ImageSetIndex]).ThrowOnError();
            gd.Api.CreateDescriptorSetLayout(device, bTDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.BufferTextureSetIndex]).ThrowOnError();
            gd.Api.CreateDescriptorSetLayout(device, bIDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.BufferImageSetIndex]).ThrowOnError();

            fixed(DescriptorSetLayout *pLayouts = layouts)
            {
                var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo()
                {
                    SType          = StructureType.PipelineLayoutCreateInfo,
                    PSetLayouts    = pLayouts,
                    SetLayoutCount = PipelineFull.DescriptorSetLayouts
                };

                gd.Api.CreatePipelineLayout(device, &pipelineLayoutCreateInfo, null, out layout).ThrowOnError();
            }

            return(layouts);
        }
    }
Beispiel #28
0
 protected virtual DescriptorSetLayout[] CreateDescriptorSetLayouts(VulkanGraphicsDevice gd, Device device, out PipelineLayout layout)
 {
     throw new NotSupportedException();
 }
Beispiel #29
0
        public TextureView(
            VulkanGraphicsDevice gd,
            Device device,
            TextureCreateInfo info,
            TextureStorage storage,
            int firstLayer,
            int firstLevel)
        {
            _gd        = gd;
            _device    = device;
            Info       = info;
            Storage    = storage;
            FirstLayer = firstLayer;
            FirstLevel = firstLevel;

            gd.Textures.Add(this);

            var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format);
            var levels = (uint)info.Levels;
            var layers = (uint)info.GetLayers();

            VkFormat = format;

            var type = info.Target.ConvertView();

            var swizzleR = info.SwizzleR.Convert();
            var swizzleG = info.SwizzleG.Convert();
            var swizzleB = info.SwizzleB.Convert();
            var swizzleA = info.SwizzleA.Convert();

            if (info.Format == GAL.Format.R5G5B5A1Unorm ||
                info.Format == GAL.Format.R5G5B5X1Unorm ||
                info.Format == GAL.Format.R5G6B5Unorm)
            {
                var temp = swizzleR;

                swizzleR = swizzleB;
                swizzleB = temp;
            }
            else if (info.Format == GAL.Format.R4G4B4A4Unorm)
            {
                var tempR = swizzleR;
                var tempG = swizzleG;

                swizzleR = swizzleA;
                swizzleG = swizzleB;
                swizzleB = tempG;
                swizzleA = tempR;
            }

            var componentMapping = new ComponentMapping(swizzleR, swizzleG, swizzleB, swizzleA);

            var aspectFlags      = info.Format.ConvertAspectFlags(info.DepthStencilMode);
            var aspectFlagsDepth = info.Format.ConvertAspectFlags(DepthStencilMode.Depth);

            var subresourceRange      = new ImageSubresourceRange(aspectFlags, (uint)firstLevel, levels, (uint)firstLayer, layers);
            var subresourceRangeDepth = new ImageSubresourceRange(aspectFlagsDepth, (uint)firstLevel, levels, (uint)firstLayer, layers);

            unsafe Auto <DisposableImageView> CreateImageView(ComponentMapping cm, ImageSubresourceRange sr, ImageViewType viewType)
            {
                var imageCreateInfo = new ImageViewCreateInfo()
                {
                    SType            = StructureType.ImageViewCreateInfo,
                    Image            = storage.GetImageForViewCreation(),
                    ViewType         = viewType,
                    Format           = format,
                    Components       = cm,
                    SubresourceRange = sr
                };

                gd.Api.CreateImageView(device, imageCreateInfo, null, out var imageView).ThrowOnError();
                return(new Auto <DisposableImageView>(new DisposableImageView(gd.Api, device, imageView), null, storage.GetImage()));
            }

            _imageView = CreateImageView(componentMapping, subresourceRange, type);

            // Framebuffer attachments and storage images requires a identity component mapping.
            var identityComponentMapping = new ComponentMapping(
                ComponentSwizzle.R,
                ComponentSwizzle.G,
                ComponentSwizzle.B,
                ComponentSwizzle.A);

            _imageViewIdentity = CreateImageView(identityComponentMapping, subresourceRangeDepth, type);

            // Framebuffer attachments also requires 3D textures to be bound as 2D array.
            if (info.Target == Target.Texture3D)
            {
                subresourceRange = new ImageSubresourceRange(aspectFlags, (uint)firstLevel, levels, (uint)firstLayer, (uint)info.Depth);

                _imageView2dArray = CreateImageView(identityComponentMapping, subresourceRange, ImageViewType.ImageViewType2DArray);
            }

            Valid = true;
        }
Beispiel #30
0
        public ShaderCollection(
            VulkanGraphicsDevice gd,
            Device device,
            IShader[] shaders,
            TransformFeedbackDescriptor[] transformFeedbackDescriptors)
        {
            _gd      = gd;
            _device  = device;
            _shaders = shaders;

            gd.Shaders.Add(this);

            var internalShaders = new Shader[shaders.Length];

            _infos = new PipelineShaderStageCreateInfo[shaders.Length];

            LinkStatus = ProgramLinkStatus.Incomplete;

            uint stages = 0;

            for (int i = 0; i < shaders.Length; i++)
            {
                var shader = (Shader)shaders[i];

                stages |= 1u << shader.StageFlags switch
                        {
                        ShaderStageFlags.ShaderStageFragmentBit => 1,
                        ShaderStageFlags.ShaderStageGeometryBit => 2,
                        ShaderStageFlags.ShaderStageTessellationControlBit => 3,
                        ShaderStageFlags.ShaderStageTessellationEvaluationBit => 4,
                        _ => 0
                    };

                internalShaders[i] = shader;
            }

            _plce = gd.PipelineLayoutCache.GetOrCreate(gd, device, stages);

            Stages = stages;

            int[][] GrabAll(Func <ShaderBindings, IReadOnlyCollection <int> > selector)
            {
                bool hasAny = false;

                int[][] bindings = new int[internalShaders.Length][];

                for (int i = 0; i < internalShaders.Length; i++)
                {
                    var collection = selector(internalShaders[i].Bindings);
                    hasAny     |= collection.Count != 0;
                    bindings[i] = collection.ToArray();
                }

                return(hasAny ? bindings : Array.Empty <int[]>());
            }

            Bindings = new[]
            {
                GrabAll(x => x.UniformBufferBindings),
                GrabAll(x => x.StorageBufferBindings),
                GrabAll(x => x.TextureBindings),
                GrabAll(x => x.ImageBindings),
                GrabAll(x => x.BufferTextureBindings),
                GrabAll(x => x.BufferImageBindings)
            };
        }