Example #1
0
        protected virtual void CreateResources()
        {
            query_count_ = (uint)QUERY_HSIZE * 2;
            for (int i = 0; i < 3; i++)
            {
                query_pool[i] = new VkQueryPool(VkQueryType.Timestamp, query_count_);
            }

            uint[] queue_families = null;

            VkSharingMode sharingMode = VkSharingMode.Exclusive;

            if (Device.QFGraphics != Device.QFCompute)
            {
                sharingMode    = VkSharingMode.Concurrent;
                queue_families = new[] { Device.QFGraphics, Device.QFCompute };
            }

            uboCluster = new SharedBuffer(VkBufferUsageFlags.UniformBuffer, VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent,
                                          (uint)Utilities.SizeOf <ClusterUBO>(), sharingMode, queue_families);

            uint max_grid_count = ((MAX_WIDTH - 1) / TILE_WIDTH + 1) * ((MAX_HEIGHT - 1) / TILE_HEIGHT + 1) * TILE_COUNT_Z;

            gridFlags = Buffer.CreateTexelBuffer(VkBufferUsageFlags.TransferDst, max_grid_count, VkFormat.R8UInt, sharingMode, queue_families);

            clusterLayout1 = new DescriptorSetLayout
            {
                new DescriptorSetLayoutBinding(0, VkDescriptorType.UniformBuffer, VkShaderStageFlags.Fragment),
                new DescriptorSetLayoutBinding(1, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Fragment),
            };

            clusterSet1 = new DescriptorSet(clusterLayout1, uboCluster, gridFlags);
        }
Example #2
0
        public Buffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropFlags, ulong stride, ulong count,
                      VkSharingMode sharingMode = VkSharingMode.Exclusive, uint[] queueFamilyIndices = null, IntPtr data = default)
        {
            Stride = stride;
            Count  = count;
            Size   = stride * count;

            // Create the buffer handle
            var bufferCreateInfo = new VkBufferCreateInfo(usageFlags, Size, queueFamilyIndices)
            {
                sharingMode = sharingMode
            };

            if (data != null && (memoryPropertyFlags & VkMemoryPropertyFlags.HostCoherent) == 0)
            {
                bufferCreateInfo.usage |= VkBufferUsageFlags.TransferDst;
            }

            handle = Device.CreateBuffer(ref bufferCreateInfo);

            UsageFlags          = usageFlags;
            memoryPropertyFlags = memoryPropFlags;

            Device.GetBufferMemoryRequirements(handle, out VkMemoryRequirements memReqs);
            Allocate(memReqs);
            Device.BindBufferMemory(handle, memory, 0);

            if (data != IntPtr.Zero)
            {
                SetData(data, 0, Size);
            }

            SetupDescriptor();
        }
Example #3
0
        /// <summary>
        /// Create a new Image.
        /// </summary>
        /// <remarks>Initial layout will be automatically set to Undefined if tiling is optimal and Preinitialized if tiling is linear.</remarks>
        /// <param name="device">The logical device that create the image.</param>
        /// <param name="format">format and type of the texel blocks that will be contained in the image</param>
        /// <param name="usage">bitmask describing the intended usage of the image.</param>
        /// <param name="_memoryPropertyFlags">Memory property flags.</param>
        /// <param name="width">number of data in the X dimension of the image.</param>
        /// <param name="height">number of data in the Y dimension of the image.</param>
        /// <param name="type">value specifying the basic dimensionality of the image. Layers in array textures do not count as a dimension for the purposes of the image type.</param>
        /// <param name="samples">number of sample per texel.</param>
        /// <param name="tiling">tiling arrangement of the texel blocks in memory.</param>
        /// <param name="mipsLevels">describes the number of levels of detail available for minified sampling of the image.</param>
        /// <param name="layers">number of layers in the image.</param>
        /// <param name="depth">number of data in the Z dimension of the image</param>
        /// <param name="createFlags">bitmask describing additional parameters of the image.</param>
        /// <param name="sharingMode">value specifying the sharing mode of the image when it will be accessed by multiple queue families.</param>
        /// <param name="queuesFamillies">list of queue families that will access this image (ignored if sharingMode is not CONCURRENT).</param>
        public Image(Device device, VkFormat format, VkImageUsageFlags usage, VkMemoryPropertyFlags _memoryPropertyFlags,
                     uint width, uint height,
                     VkImageType type               = VkImageType.Image2D, VkSampleCountFlags samples = VkSampleCountFlags.SampleCount1,
                     VkImageTiling tiling           = VkImageTiling.Optimal, uint mipsLevels          = 1, uint layers = 1, uint depth = 1,
                     VkImageCreateFlags createFlags = 0, VkSharingMode sharingMode                    = VkSharingMode.Exclusive, params uint[] queuesFamillies)
            : base(device, _memoryPropertyFlags)
        {
            info.imageType     = type;
            info.format        = format;
            info.extent.width  = width;
            info.extent.height = height;
            info.extent.depth  = depth;
            info.mipLevels     = mipsLevels;
            info.arrayLayers   = layers;
            info.samples       = samples;
            info.tiling        = tiling;
            info.usage         = usage;
            info.initialLayout = (tiling == VkImageTiling.Optimal) ? VkImageLayout.Undefined : VkImageLayout.Preinitialized;
            info.sharingMode   = sharingMode;
            info.flags         = createFlags;

            this.queueFalillies = queuesFamillies;
            lastKnownLayout     = info.initialLayout;

            Activate();
        }
 internal SwapchainKHRBuilder(SurfaceKHR surf, Device dev, VkExtent2D size)
 {
     _surf               = surf;
     _dev                = dev;
     _extent             = size;
     _shareMode          = VkSharingMode.Exclusive;
     _preferredTransform = 0;
     _requiredTransform  = VkSurfaceTransformFlagBitsKHR.InheritBitKhr;
 }
Example #5
0
 public SharedBuffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropFlags, ulong size,
                     VkSharingMode sharingMode = VkSharingMode.Exclusive, uint[] queueFamilyIndices = null)
 {
     buffers[0] = new Buffer(usageFlags, memoryPropFlags, size, 1, sharingMode, queueFamilyIndices);
     buffers[0].Map(0, size);
     buffers[1] = new Buffer(usageFlags, memoryPropFlags, size, 1, sharingMode, queueFamilyIndices);
     buffers[1].Map(0, size);
     buffers[2] = new Buffer(usageFlags, memoryPropFlags, size, 1, sharingMode, queueFamilyIndices);
     buffers[2].Map(0, size);
 }
Example #6
0
        public ImagePooled(Device dev, VkFormat format, VkImageType type, VkExtent3D size, uint mipLevels,
                           uint arrayLayers, VkImageTiling tiling, VkSampleCountFlag samples, VkImageUsageFlag usage,
                           VkImageCreateFlag flags, VkSharingMode sharing = VkSharingMode.Exclusive, uint[] sharedQueueFamily = null) :
            base(dev, format, type, size, mipLevels, arrayLayers, tiling, samples, usage, flags, sharing,
                 sharedQueueFamily)
        {
            var memReq  = MemoryRequirements;
            var memType = memReq.FindMemoryType(dev.PhysicalDevice);

            Memory = dev.MemoryPool.Allocate(memType, DeviceMemoryPools.Pool.TexturePool, memReq.TypeRequirements.Size);
            BindMemory(Memory.BackingMemory, Memory.Offset);
        }
Example #7
0
        public Image(Device dev, VkFormat format, VkImageType type, VkExtent3D size, uint mipLevels, uint arrayLayers,
                     VkImageTiling tiling, VkSampleCountFlag samples, VkImageUsageFlag usage, VkImageCreateFlag flags,
                     VkSharingMode sharing    = VkSharingMode.Exclusive,
                     uint[] sharedQueueFamily = null)
        {
            Device      = dev;
            Format      = format;
            Dimensions  = size;
            MipmapCount = mipLevels;
            LayerCount  = arrayLayers;
            unsafe
            {
#if DEBUG
                var properties = Device.PhysicalDevice.Handle.GetPhysicalDeviceImageFormatProperties(format, type,
                                                                                                     tiling, usage, flags);
#endif
                if (sharing == VkSharingMode.Concurrent)
                    Debug.Assert(sharedQueueFamily != null);
                fixed(uint *sharedPtr = sharedQueueFamily)
                {
                    var info = new VkImageCreateInfo()
                    {
                        SType               = VkStructureType.ImageCreateInfo,
                        Format              = format,
                        ImageType           = type,
                        Tiling              = tiling,
                        Extent              = size,
                        ArrayLayers         = arrayLayers,
                        MipLevels           = mipLevels,
                        Flags               = flags,
                        InitialLayout       = VkImageLayout.Undefined,
                        PNext               = IntPtr.Zero,
                        PQueueFamilyIndices = sharedPtr,
                        SharingMode         = sharing,
                        Samples             = samples,
                        Usage               = usage
                    };

                    Handle = Device.Handle.CreateImage(&info, Instance.AllocationCallbacks);
                }
            }
        }
        private void InitLightCompute()
        {
            uint[] queue_families = null;

            VkSharingMode sharingMode = VkSharingMode.Exclusive;

            if (Device.QFGraphics != Device.QFCompute)
            {
                sharingMode    = VkSharingMode.Concurrent;
                queue_families = new[] { Device.QFGraphics, Device.QFCompute };
            }

            uint max_grid_count = ((MAX_WIDTH - 1) / TILE_WIDTH + 1) * ((MAX_HEIGHT - 1) / TILE_HEIGHT + 1) * TILE_COUNT_Z;

            light_pos_ranges = new SharedBuffer(VkBufferUsageFlags.StorageTexelBuffer, VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent,
                                                MAX_NUM_LIGHTS * 4 * sizeof(float), VkSharingMode.Exclusive, queue_families);
            light_pos_ranges.CreateView(VkFormat.R32G32B32A32SFloat);

            light_colors = new SharedBuffer(VkBufferUsageFlags.StorageTexelBuffer, VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent,
                                            MAX_NUM_LIGHTS * sizeof(uint), sharingMode, queue_families);
            light_colors.CreateView(VkFormat.R8G8B8A8UNorm);

            lightBounds            = Buffer.CreateTexelBuffer(VkBufferUsageFlags.TransferDst, MAX_NUM_LIGHTS * 6 * sizeof(uint), VkFormat.R32UInt, sharingMode, queue_families); // max tile count 1d (z 256)
            gridLightCounts        = Buffer.CreateTexelBuffer(VkBufferUsageFlags.TransferDst, max_grid_count * sizeof(uint), VkFormat.R32UInt, sharingMode, queue_families);     // light count / grid
            gridLightCountTotal    = Buffer.CreateTexelBuffer(VkBufferUsageFlags.TransferDst, sizeof(uint), VkFormat.R32UInt, sharingMode, queue_families);                      // light count total * max grid count
            gridLightCountOffsets  = Buffer.CreateTexelBuffer(VkBufferUsageFlags.TransferDst, max_grid_count * sizeof(uint), VkFormat.R32UInt, sharingMode, queue_families);     // same as above
            lightList              = Buffer.CreateTexelBuffer(VkBufferUsageFlags.TransferDst, 1024 * 1024 * sizeof(uint), VkFormat.R32UInt, sharingMode, queue_families);        // light idx
            gridLightCountsCompare = Buffer.CreateTexelBuffer(VkBufferUsageFlags.TransferDst, max_grid_count * sizeof(uint), VkFormat.R32UInt, sharingMode, queue_families);     // light count / grid

            resourceLayout0 = new DescriptorSetLayout(1)
            {
                new DescriptorSetLayoutBinding(0, VkDescriptorType.UniformBuffer, VkShaderStageFlags.Fragment),
                new DescriptorSetLayoutBinding(1, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Fragment),
                new DescriptorSetLayoutBinding(2, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Fragment),
            };

            resourceLayout1 = new DescriptorSetLayout(2)
            {
                new DescriptorSetLayoutBinding(0, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Fragment),
                new DescriptorSetLayoutBinding(1, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Fragment),
                new DescriptorSetLayoutBinding(2, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Fragment),
                new DescriptorSetLayoutBinding(3, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Fragment),
                new DescriptorSetLayoutBinding(4, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Fragment),
                new DescriptorSetLayoutBinding(5, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Fragment),
                new DescriptorSetLayoutBinding(6, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Fragment),
            };

            resourceSet1 = new DescriptorSet(resourceLayout0, uboCluster, light_pos_ranges, light_colors);
            resourceSet2 = new DescriptorSet(resourceLayout1, gridFlags, lightBounds, gridLightCounts, gridLightCountTotal,
                                             gridLightCountOffsets, lightList, gridLightCountsCompare);


            clusterLight = Resources.Instance.Load <Shader>("Shaders/ClusterLight.shader");

            computeLayout0 = new DescriptorSetLayout
            {
                new DescriptorSetLayoutBinding(0, VkDescriptorType.UniformBuffer, VkShaderStageFlags.Compute),
                new DescriptorSetLayoutBinding(1, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Compute),
                new DescriptorSetLayoutBinding(2, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Compute),
            };

            computeLayout1 = new DescriptorSetLayout
            {
                new DescriptorSetLayoutBinding(0, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Compute),
                new DescriptorSetLayoutBinding(1, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Compute),
                new DescriptorSetLayoutBinding(2, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Compute),
                new DescriptorSetLayoutBinding(3, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Compute),
                new DescriptorSetLayoutBinding(4, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Compute),
                new DescriptorSetLayoutBinding(5, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Compute),
                new DescriptorSetLayoutBinding(6, VkDescriptorType.StorageTexelBuffer, VkShaderStageFlags.Compute),
            };

            computeSet0 = new DescriptorSet(computeLayout0, uboCluster, light_pos_ranges, light_colors);
            computeSet1 = new DescriptorSet(computeLayout1, gridFlags, lightBounds, gridLightCounts, gridLightCountTotal,
                                            gridLightCountOffsets, lightList, gridLightCountsCompare);
        }
Example #9
0
        public static Buffer CreateTexelBuffer(VkBufferUsageFlags flags, ulong size, VkFormat format, VkSharingMode sharingMode, uint[] queueFamilyIndices)
        {
            var buffer = new Buffer(VkBufferUsageFlags.StorageTexelBuffer | flags, VkMemoryPropertyFlags.DeviceLocal, size, 1, sharingMode, queueFamilyIndices);

            buffer.CreateView(format, 0, WholeSize);
            return(buffer);
        }
Example #10
0
 public Buffer(VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, ulong size, VkSharingMode sharingMode = VkSharingMode.Exclusive)
     : this(usageFlags, memoryPropertyFlags, size, 1, sharingMode)
 {
 }
Example #11
0
        public SwapchainKHR(SurfaceKHR surface, Device device, uint minImageCount,
                            uint layerCount, VkImageUsageFlag usageFlag,
                            VkFormat imageFormat, VkColorSpaceKHR colorSpace,
                            VkExtent2D dimensions,
                            VkCompositeAlphaFlagBitsKHR compositeAlpha,
                            VkPresentModeKHR presentMode,
                            bool clipped = true,
                            VkSurfaceTransformFlagBitsKHR transform = VkSurfaceTransformFlagBitsKHR.IdentityBitKhr,
                            VkSharingMode sharing     = VkSharingMode.Exclusive, uint[] sharedQueueFamily = null,
                            SwapchainKHR oldSwapchain = null)
        {
            SurfaceKHR = surface;
            Device     = device;

            {
                var surfSupported = false;
                foreach (var family in Device.Queues.Select(x => x.FamilyIndex).Distinct())
                {
                    if (PhysicalDevice.Handle.GetPhysicalDeviceSurfaceSupportKHR(family, SurfaceKHR.Handle))
                    {
                        surfSupported = true;
                        break;
                    }
                }
                if (!surfSupported)
                {
                    throw new NotSupportedException($"No queues on device support the surface");
                }
            }

            _sharingQueueInfo = sharedQueueFamily;

            unsafe
            {
                if (sharing == VkSharingMode.Concurrent)
                {
                    Debug.Assert(sharedQueueFamily != null);
                }
                var hasPinnedSharedQueue    = sharedQueueFamily != null && sharedQueueFamily.Length > 0;
                var pinnedSharedQueueFamily = hasPinnedSharedQueue
                    ? GCHandle.Alloc(sharedQueueFamily, GCHandleType.Pinned)
                    : default(GCHandle);
                try
                {
                    var info = new VkSwapchainCreateInfoKHR()
                    {
                        SType                 = VkStructureType.SwapchainCreateInfoKhr,
                        PNext                 = IntPtr.Zero,
                        Flags                 = 0, // reserved VkSwapchainCreateFlagBitsKHR
                        Surface               = surface.Handle,
                        MinImageCount         = minImageCount,
                        ImageFormat           = imageFormat,
                        ImageColorSpace       = colorSpace,
                        ImageExtent           = dimensions,
                        ImageArrayLayers      = layerCount,
                        ImageUsage            = usageFlag,
                        ImageSharingMode      = sharing,
                        QueueFamilyIndexCount = (uint)(sharedQueueFamily?.Length ?? 0),
                        PQueueFamilyIndices   = hasPinnedSharedQueue
                            ? (uint *)Marshal.UnsafeAddrOfPinnedArrayElement(sharedQueueFamily, 0).ToPointer()
                            : (uint *)0,
                        PreTransform   = transform,
                        CompositeAlpha = compositeAlpha,
                        PresentMode    = presentMode,
                        Clipped        = clipped,
                        OldSwapchain   = oldSwapchain?.Handle ?? VkSwapchainKHR.Null
                    };
                    _info  = info;
                    Handle = Device.Handle.CreateSwapchainKHR(&info, Instance.AllocationCallbacks);
                    if (oldSwapchain != null)
                    {
                        foreach (var img in oldSwapchain._swapchainImages)
                        {
                            img.Dispose();
                        }
                        oldSwapchain.Dispose();
                    }
                }
                finally
                {
                    if (hasPinnedSharedQueue)
                    {
                        pinnedSharedQueueFamily.Free();
                    }
                }
            }

            var images = Device.Handle.GetSwapchainImagesKHR(Handle);

            _swapchainImages.Clear();
            _swapchainImages.Capacity = images.Length;
            foreach (var img in images)
            {
                _swapchainImages.Add(new SwapchainImage(this, img));
            }
        }
Example #12
0
        /// <summary>
        /// Create a vulkan buffer and automatically activate it. Automatic activation on startup implies to explicitly dispose the buffer.
        /// </summary>
        /// <param name="device">Logical Device.</param>
        /// <param name="usage">a bitmask specifying allowed usages of the buffer</param>
        /// <param name="_memoryPropertyFlags">Memory property flags.</param>
        /// <param name="size">Desired size in byte of the buffer to be created.</param>
        /// <param name="sharingMode">value specifying the sharing mode of the buffer when it will be accessed by multiple queue familie</param>
        public Buffer(Device device, VkBufferUsageFlags usage, VkMemoryPropertyFlags _memoryPropertyFlags, UInt64 size, VkSharingMode sharingMode = VkSharingMode.Exclusive)
            : base(device, _memoryPropertyFlags)
        {
            createInfo.size        = size;
            createInfo.usage       = usage;
            createInfo.sharingMode = VkSharingMode.Exclusive;

            Activate();
        }
 public SwapchainKHRBuilder Concurrent(params uint[] queues)
 {
     _shareMode         = VkSharingMode.Concurrent;
     _sharingParameters = queues;
     return(this);
 }
 public SwapchainKHRBuilder Exclusive()
 {
     _shareMode         = VkSharingMode.Exclusive;
     _sharingParameters = null;
     return(this);
 }
Example #15
0
        public FDataBuffer(VkDevice device, VkPhysicalDevice physicalDevice, int length, VkBufferUsageFlags usage, VkSharingMode sharingMode)
        {
            this.device = device;

            VkBufferCreateInfo createInfo = VkBufferCreateInfo.New();

            size                   = (ulong)(sizeof(T) * length);
            createInfo.size        = size;
            createInfo.usage       = usage;
            createInfo.sharingMode = sharingMode;

            VkBuffer buffer = VkBuffer.Null;

            Assert(vkCreateBuffer(device, &createInfo, null, &buffer));
            this.Buffer = buffer;

            VkMemoryRequirements memoryRequirements = new VkMemoryRequirements();

            vkGetBufferMemoryRequirements(device, this.Buffer, &memoryRequirements);

            VkPhysicalDeviceMemoryProperties memoryProperties = new VkPhysicalDeviceMemoryProperties();

            vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties);

            VkMemoryAllocateInfo allocateInfo = VkMemoryAllocateInfo.New();

            allocateInfo.allocationSize  = memoryRequirements.size;
            allocateInfo.memoryTypeIndex = SelectMemoryType(memoryProperties, memoryRequirements.memoryTypeBits,
                                                            VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent);

            VkDeviceMemory memory = new VkDeviceMemory();

            Assert(vkAllocateMemory(device, &allocateInfo, null, &memory));
            Memory = memory;

            Assert(vkBindBufferMemory(device, this.Buffer, memory, 0));

            spanLength = length;
        }