예제 #1
0
        public void CreatePipelineLayout()
        {
            var createInfo = new PipelineLayoutCreateInfo();

            using (Device.CreatePipelineLayout(createInfo)) { }
            using (Device.CreatePipelineLayout(createInfo, CustomAllocator)) { }
        }
예제 #2
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);
        }
        private PipelineLayout CreatePipelineLayout(DescriptorSetLayout descriptorSetLayout)
        {
            var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo
            {
                SetLayouts = new DescriptorSetLayout[] { descriptorSetLayout }
            };

            return(VulkanRenderer.SelectedLogicalDevice.CreatePipelineLayout(pipelineLayoutCreateInfo));
        }
예제 #4
0
        void CreateComputePipeline()
        {
            /*
             * We create a compute pipeline here.
             */

            /*
             * Create a shader module. A shader module basically just encapsulates some shader code.
             */
            // the code in comp.spv was created by running the command:
            // glslangValidator.exe -V shader.comp
            byte[] code = ReadFile("shaders/shader.comp.spv");
            ShaderModuleCreateInfo createInfo = new ShaderModuleCreateInfo()
            {
                Code = code
            };

            computeShaderModule = device.CreateShaderModule(createInfo);

            /*
             * Now let us actually create the compute pipeline.
             * A compute pipeline is very simple compared to a graphics pipeline.
             * It only consists of a single stage with a compute shader.
             * So first we specify the compute shader stage, and it's entry point(main).
             */
            PipelineShaderStageCreateInfo shaderStageCreateInfo = new PipelineShaderStageCreateInfo()
            {
                Stage  = ShaderStages.Compute,// VK_SHADER_STAGE_COMPUTE_BIT;
                Module = computeShaderModule,
                Name   = "main"
            };

            /*
             * The pipeline layout allows the pipeline to access descriptor sets.
             * So we just specify the descriptor set layout we created earlier.
             */
            PipelineLayoutCreateInfo pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo(new[] { descriptorSetLayout });

            pipelineLayout = device.CreatePipelineLayout(pipelineLayoutCreateInfo);

            ComputePipelineCreateInfo pipelineCreateInfo = new ComputePipelineCreateInfo()
            {
                Stage  = shaderStageCreateInfo,
                Layout = pipelineLayout
            };

            /*
             * Now, we finally create the compute pipeline.
             */
            ComputePipelineCreateInfo[] ci = { pipelineCreateInfo };
            pipelines = device.CreateComputePipelines(ci);
        }
예제 #5
0
        PipelineLayout CreatePipelineLayout()
        {
            // The pipeline layout represents a sequence of descriptor sets with each having a
            // specific layout. This sequence of layouts is used to determine the interface between
            // shader stages and shader resources. Each pipeline is created using a pipeline layout.

            // We're not using any resources in this example so we dont
            // need to create any descriptor sets

            var createInfo = new PipelineLayoutCreateInfo();

            return(device.CreatePipelineLayout(createInfo));
        }
예제 #6
0
        private void CreateComputePipeline()
        {
            var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo(new[] { _descriptorSetLayout });

            _pipelineLayout = Device.Logical.CreatePipelineLayout(pipelineLayoutCreateInfo);

            using (ShaderModule shader = Device.Logical.CreateShaderModule(new ShaderModuleCreateInfo(SpirV)))
            {
                var computePipelineCreateInfo = new ComputePipelineCreateInfo(
                    new PipelineShaderStageCreateInfo(ShaderStages.Compute, shader, "main"),
                    _pipelineLayout);
                _pipeline = Device.Logical.CreateComputePipeline(computePipelineCreateInfo);
            }
        }
예제 #7
0
        public unsafe PipelineLayout(Api api, DescriptorSetLayout descriptorSetLayout)
        {
            _api = api;

            var descriptorSetLayouts = descriptorSetLayout.VkDescriptorSetLayout;

            var pipelineLayoutInfo = new PipelineLayoutCreateInfo();

            pipelineLayoutInfo.SType                  = StructureType.PipelineLayoutCreateInfo;
            pipelineLayoutInfo.SetLayoutCount         = 1;
            pipelineLayoutInfo.PSetLayouts            = (VkDescriptorSetLayout *)Unsafe.AsPointer(ref descriptorSetLayouts);
            pipelineLayoutInfo.PushConstantRangeCount = 0;
            pipelineLayoutInfo.PPushConstantRanges    = (PushConstantRange *)0;

            Util.Verify(_api.Vk.CreatePipelineLayout(_api.Device.VkDevice, pipelineLayoutInfo, default, out _vkPipelineLayout), $"{nameof(PipelineLayout)}: Failed to create pipeline layout");
예제 #8
0
        PipelineLayout CreatePipelineLayout()
        {
            var layout_create_info = new PipelineLayoutCreateInfo
            {
                sType                  = StructureType.PipelineLayoutCreateInfo, // VkStructureType                sType
                pNext                  = IntPtr.Zero,                            // const void                    *pNext
                flags                  = 0,                                      // VkPipelineLayoutCreateFlagBits    flags
                setLayoutCount         = 0,                                      // uint32_t                       setLayoutCount
                pSetLayouts            = (DescriptorSetLayout *)0,               // const VkDescriptorSetLayout   *pSetLayouts
                pushConstantRangeCount = 0,                                      // uint32_t                       pushConstantRangeCount
                pPushConstantRanges    = (PushConstantRange *)0                  // const VkPushConstantRange     *pPushConstantRanges
            };

            PipelineLayout pipeline_layout;

            vk.CreatePipelineLayout(GetDevice, ref layout_create_info, (AllocationCallbacks *)0, out pipeline_layout).CheckError();
            return(pipeline_layout);
        }
예제 #9
0
        private PipelineLayout CreatePipelineLayout()
        {
            PipelineLayoutCreateInfo createInfo = new PipelineLayoutCreateInfo
            {
                SType = StructureType.PipelineLayoutCreateInfo
            };

            fixed(DescriptorSetLayout *pLayouts = this.DescriptorSetLayouts)
            {
                createInfo.SetLayoutCount = (uint)this.DescriptorSetLayouts.Length;
                createInfo.PSetLayouts    = pLayouts;

                PipelineLayout pipelineLayout;
                var            res = VkApi.CreatePipelineLayout(this.Device, &createInfo, null, &pipelineLayout);

                if (res != Result.Success)
                {
                    throw new VMASharp.VulkanResultException("Failed to create Pipeline Layout!", res);
                }

                return(pipelineLayout);
            }
        }
예제 #10
0
        protected PipelineLayout CreatePipelineLayout(DescriptorSetLayout descriptorSetLayout)
        {
            var createInfo = new PipelineLayoutCreateInfo(new[] { descriptorSetLayout }, null);

            return(device.CreatePipelineLayout(createInfo));
        }
예제 #11
0
        Pipeline[] CreatePipelines()
        {
            var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo {
                SetLayouts = new DescriptorSetLayout [] { descriptorSetLayout }
            };

            pipelineLayout = device.CreatePipelineLayout(pipelineLayoutCreateInfo);
            var vertexShaderModule   = device.CreateShaderModule(LoadResource("XLogo.Shaders.shader.vert.spv"));
            var fragmentShaderModule = device.CreateShaderModule(LoadResource("XLogo.Shaders.shader.frag.spv"));

            PipelineShaderStageCreateInfo [] pipelineShaderStages =
            {
                new PipelineShaderStageCreateInfo {
                    Stage  = ShaderStageFlags.Vertex,
                    Module = vertexShaderModule,
                    Name   = "main"
                },
                new PipelineShaderStageCreateInfo {
                    Stage  = ShaderStageFlags.Fragment,
                    Module = fragmentShaderModule,
                    Name   = "main"
                }
            };
            var viewport = new Viewport {
                MinDepth = 0,
                MaxDepth = 1.0f,
                Width    = surfaceCapabilities.CurrentExtent.Width,
                Height   = surfaceCapabilities.CurrentExtent.Height
            };
            var scissor = new Rect2D {
                Extent = surfaceCapabilities.CurrentExtent
            };
            var viewportCreateInfo = new PipelineViewportStateCreateInfo {
                Viewports = new Viewport [] { viewport },
                Scissors  = new Rect2D [] { scissor }
            };

            var multisampleCreateInfo = new PipelineMultisampleStateCreateInfo {
                RasterizationSamples = SampleCountFlags.Count1,
                SampleMask           = new uint [] { ~0u }
            };
            var colorBlendAttachmentState = new PipelineColorBlendAttachmentState {
                ColorWriteMask = ColorComponentFlags.R | ColorComponentFlags.G | ColorComponentFlags.B | ColorComponentFlags.A
            };
            var colorBlendStateCreatInfo = new PipelineColorBlendStateCreateInfo {
                LogicOp     = LogicOp.Copy,
                Attachments = new PipelineColorBlendAttachmentState [] { colorBlendAttachmentState }
            };
            var rasterizationStateCreateInfo = new PipelineRasterizationStateCreateInfo {
                PolygonMode = PolygonMode.Fill,
                CullMode    = (uint)CullModeFlags.None,
                FrontFace   = FrontFace.Clockwise,
                LineWidth   = 1.0f
            };
            var inputAssemblyStateCreateInfo = new PipelineInputAssemblyStateCreateInfo {
                Topology = PrimitiveTopology.TriangleList
            };
            var vertexInputBindingDescription = new VertexInputBindingDescription {
                Stride    = 3 * sizeof(float),
                InputRate = VertexInputRate.Vertex
            };
            var vertexInputAttributeDescription = new VertexInputAttributeDescription {
                Format = Format.R32g32b32Sfloat
            };
            var vertexInputStateCreateInfo = new PipelineVertexInputStateCreateInfo {
                VertexBindingDescriptions   = new VertexInputBindingDescription [] { vertexInputBindingDescription },
                VertexAttributeDescriptions = new VertexInputAttributeDescription [] { vertexInputAttributeDescription }
            };

            var pipelineCreateInfo = new GraphicsPipelineCreateInfo {
                Layout             = pipelineLayout,
                ViewportState      = viewportCreateInfo,
                Stages             = pipelineShaderStages,
                MultisampleState   = multisampleCreateInfo,
                ColorBlendState    = colorBlendStateCreatInfo,
                RasterizationState = rasterizationStateCreateInfo,
                InputAssemblyState = inputAssemblyStateCreateInfo,
                VertexInputState   = vertexInputStateCreateInfo,
                DynamicState       = new PipelineDynamicStateCreateInfo(),
                RenderPass         = renderPass
            };

            return(device.CreateGraphicsPipelines(device.CreatePipelineCache(new PipelineCacheCreateInfo()), new GraphicsPipelineCreateInfo [] { pipelineCreateInfo }));
        }
예제 #12
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);
        }
    }
예제 #13
0
        private PipelineLayout CreatePipelineLayout()
        {
            var layoutCreateInfo = new PipelineLayoutCreateInfo();

            return(Context.Device.CreatePipelineLayout(layoutCreateInfo));
        }
예제 #14
0
 public unsafe PipelineLayout CreatePipelineLayout(ref PipelineLayoutCreateInfo createInfo, AllocationCallbacks* allocator = null)
 {
     PipelineLayout pipelineLayout;
     fixed (PipelineLayoutCreateInfo* __createInfo__ = &createInfo)
     {
         vkCreatePipelineLayout(this, __createInfo__, allocator, &pipelineLayout).CheckError();
     }
     return pipelineLayout;
 }
        private unsafe void CreatePipelineLayout(PipelineStateDescription pipelineStateDescription)
        {
            // Remap descriptor set indices to those in the shader. This ordering generated by the ShaderCompiler
            var resourceGroups = pipelineStateDescription.EffectBytecode.Reflection.ResourceBindings.Select(x => x.ResourceGroup ?? "Globals").Distinct().ToList();

            ResourceGroupCount = resourceGroups.Count;

            var layouts = pipelineStateDescription.RootSignature.EffectDescriptorSetReflection.Layouts;

            // Get binding indices used by the shader
            var destinationBindings = pipelineStateDescription.EffectBytecode.Stages
                                      .SelectMany(x => BinarySerialization.Read <ShaderInputBytecode>(x.Data).ResourceBindings)
                                      .GroupBy(x => x.Key, x => x.Value)
                                      .ToDictionary(x => x.Key, x => x.First());

            var maxBindingIndex    = destinationBindings.Max(x => x.Value);
            var destinationEntries = new DescriptorSetLayoutBuilder.Entry[maxBindingIndex + 1];

            DescriptorBindingMapping = new List <DescriptorSetInfo>();

            for (int i = 0; i < resourceGroups.Count; i++)
            {
                var resourceGroupName = resourceGroups[i] == "Globals" ? pipelineStateDescription.RootSignature.EffectDescriptorSetReflection.DefaultSetSlot : resourceGroups[i];
                var layoutIndex       = resourceGroups[i] == null ? 0 : layouts.FindIndex(x => x.Name == resourceGroupName);

                // Check if the resource group is used by the shader
                if (layoutIndex == -1)
                {
                    continue;
                }

                var sourceEntries = layouts[layoutIndex].Layout.Entries;

                for (int sourceBinding = 0; sourceBinding < sourceEntries.Count; sourceBinding++)
                {
                    var sourceEntry = sourceEntries[sourceBinding];

                    int destinationBinding;
                    if (destinationBindings.TryGetValue(sourceEntry.Key.Name, out destinationBinding))
                    {
                        destinationEntries[destinationBinding] = sourceEntry;

                        // No need to umpdate immutable samplers
                        if (sourceEntry.Class == EffectParameterClass.Sampler && sourceEntry.ImmutableSampler != null)
                        {
                            continue;
                        }

                        DescriptorBindingMapping.Add(new DescriptorSetInfo
                        {
                            SourceSet                = layoutIndex,
                            SourceBinding            = sourceBinding,
                            DestinationBinding       = destinationBinding,
                            DescriptorType           = VulkanConvertExtensions.ConvertDescriptorType(sourceEntry.Class, sourceEntry.Type),
                            ResourceElementIsInteger = sourceEntry.ElementType != EffectParameterType.Float && sourceEntry.ElementType != EffectParameterType.Double,
                        });
                    }
                }
            }

            // Create default sampler, used by texture and buffer loads
            destinationEntries[0] = new DescriptorSetLayoutBuilder.Entry
            {
                Class            = EffectParameterClass.Sampler,
                Type             = EffectParameterType.Sampler,
                ImmutableSampler = GraphicsDevice.SamplerStates.PointWrap,
                ArraySize        = 1,
            };

            // Create descriptor set layout
            NativeDescriptorSetLayout = DescriptorSetLayout.CreateNativeDescriptorSetLayout(GraphicsDevice, destinationEntries, out DescriptorTypeCounts);

            // Create pipeline layout
            var nativeDescriptorSetLayout = NativeDescriptorSetLayout;
            var pipelineLayoutCreateInfo  = new PipelineLayoutCreateInfo
            {
                StructureType  = StructureType.PipelineLayoutCreateInfo,
                SetLayoutCount = 1,
                SetLayouts     = new IntPtr(&nativeDescriptorSetLayout)
            };

            NativeLayout = GraphicsDevice.NativeDevice.CreatePipelineLayout(ref pipelineLayoutCreateInfo);
        }
예제 #16
0
 internal static unsafe extern Result vkCreatePipelineLayout(Device device, PipelineLayoutCreateInfo* createInfo, AllocationCallbacks* allocator, PipelineLayout* pipelineLayout);
예제 #17
0
        private unsafe void CreatePipelineLayout()
        {
            var binding = new DescriptorSetLayoutBinding
            {
                Binding         = 0,
                DescriptorCount = 1,
                DescriptorType  = DescriptorType.UniformBuffer,
                StageFlags      = ShaderStageFlags.Vertex
            };

            var descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo
            {
                StructureType = StructureType.DescriptorSetLayoutCreateInfo,
                BindingCount  = 1,
                Bindings      = new IntPtr(&binding)
            };

            descriptorSetLayout = device.CreateDescriptorSetLayout(ref descriptorSetLayoutCreateInfo);

            var localDescriptorSetLayout = descriptorSetLayout;
            var createInfo = new PipelineLayoutCreateInfo
            {
                StructureType  = StructureType.PipelineLayoutCreateInfo,
                SetLayoutCount = 1,
                SetLayouts     = new IntPtr(&localDescriptorSetLayout)
            };

            pipelineLayout = device.CreatePipelineLayout(ref createInfo);

            var poolSize = new DescriptorPoolSize {
                DescriptorCount = 2, Type = DescriptorType.UniformBuffer
            };
            var descriptorPoolCreateinfo = new DescriptorPoolCreateInfo
            {
                StructureType = StructureType.DescriptorPoolCreateInfo,
                PoolSizeCount = 1,
                PoolSizes     = new IntPtr(&poolSize),
                MaxSets       = 2
            };

            descriptorPool = device.CreateDescriptorPool(ref descriptorPoolCreateinfo);

            var bufferCreateInfo = new BufferCreateInfo
            {
                StructureType = StructureType.BufferCreateInfo,
                Usage         = BufferUsageFlags.UniformBuffer,
                Size          = 64,
            };

            uniformBuffer = device.CreateBuffer(ref bufferCreateInfo);

            MemoryRequirements memoryRequirements;

            device.GetBufferMemoryRequirements(uniformBuffer, out memoryRequirements);
            var memory = AllocateMemory(MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent, memoryRequirements);

            device.BindBufferMemory(uniformBuffer, memory, 0);

            var mappedMemory = device.MapMemory(memory, 0, 64, MemoryMapFlags.None);
            var data         = new[]
            {
                1.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 1.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 1.0f, 0.0f,
                0.0f, 0.0f, 0.0f, 1.0f,
            };

            Utilities.Write(mappedMemory, data, 0, data.Length);
            device.UnmapMemory(memory);
        }
예제 #18
0
        public static unsafe DescriptorSetLayout[] CreateMinimal(VulkanRenderer gd, Device device, ShaderSource[] shaders, out PipelineLayout layout)
        {
            int stagesCount = shaders.Length;

            int uCount = 0;
            int tCount = 0;
            int iCount = 0;

            foreach (var shader in shaders)
            {
                uCount += shader.Bindings.UniformBufferBindings.Count;
                tCount += shader.Bindings.TextureBindings.Count;
                iCount += shader.Bindings.ImageBindings.Count;
            }

            DescriptorSetLayoutBinding *uLayoutBindings = stackalloc DescriptorSetLayoutBinding[uCount];
            DescriptorSetLayoutBinding *sLayoutBindings = stackalloc DescriptorSetLayoutBinding[stagesCount];
            DescriptorSetLayoutBinding *tLayoutBindings = stackalloc DescriptorSetLayoutBinding[tCount];
            DescriptorSetLayoutBinding *iLayoutBindings = stackalloc DescriptorSetLayoutBinding[iCount];

            int uIndex = 0;
            int sIndex = 0;
            int tIndex = 0;
            int iIndex = 0;

            foreach (var shader in shaders)
            {
                var stageFlags = shader.Stage.Convert();

                void Set(DescriptorSetLayoutBinding *bindings, DescriptorType type, ref int start, IEnumerable <int> bds)
                {
                    foreach (var b in bds)
                    {
                        bindings[start++] = new DescriptorSetLayoutBinding
                        {
                            Binding         = (uint)b,
                            DescriptorType  = type,
                            DescriptorCount = 1,
                            StageFlags      = stageFlags
                        };
                    }
                }

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

                // TODO: Support buffer textures and images here.
                // This is only used for the helper shaders on the backend, and we don't use buffer textures on them
                // so far, so it's not really necessary right now.
                Set(uLayoutBindings, DescriptorType.UniformBuffer, ref uIndex, shader.Bindings.UniformBufferBindings);
                SetStorage(sLayoutBindings, ref sIndex, shader.Bindings.StorageBufferBindings.Count);
                Set(tLayoutBindings, DescriptorType.CombinedImageSampler, ref tIndex, shader.Bindings.TextureBindings);
                Set(iLayoutBindings, DescriptorType.StorageImage, ref iIndex, shader.Bindings.ImageBindings);
            }

            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
            };

            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();

            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);
        }
예제 #19
0
        public static PipelineLayout CreatePipelineLayout(Graphics g, params DescriptorSetLayout[] setLayouts)
        {
            var layoutCreateInfo = new PipelineLayoutCreateInfo(setLayouts);

            return(g.Context.Device.CreatePipelineLayout(layoutCreateInfo));
        }
예제 #20
0
        //[HandleProcessCorruptedStateExceptionsAttribute, SecurityCriticalAttribute]
        private unsafe void Recreate()
        {
            errorDuringCreate = false;

            if (Description.RootSignature == null)
            {
                return;
            }

            PipelineShaderStageCreateInfo[] stages;

            // create render pass
            bool hasDepthStencilAttachment = Description.Output.DepthStencilFormat != PixelFormat.None;

            var renderTargetCount = Description.Output.RenderTargetCount;

            var attachmentCount = renderTargetCount;

            if (hasDepthStencilAttachment)
            {
                attachmentCount++;
            }

            var attachments = new AttachmentDescription[attachmentCount];
            var colorAttachmentReferences = new AttachmentReference[renderTargetCount];

            fixed(PixelFormat *renderTargetFormat = &Description.Output.RenderTargetFormat0)
            fixed(BlendStateRenderTargetDescription * blendDescription = &Description.BlendState.RenderTarget0)
            {
                for (int i = 0; i < renderTargetCount; i++)
                {
                    var currentBlendDesc = Description.BlendState.IndependentBlendEnable ? (blendDescription + i) : blendDescription;

                    attachments[i] = new AttachmentDescription
                    {
                        Format                = VulkanConvertExtensions.ConvertPixelFormat(*(renderTargetFormat + i)),
                        Samples               = SampleCountFlags.Sample1,
                        LoadOperation         = currentBlendDesc->BlendEnable ? AttachmentLoadOperation.Load : AttachmentLoadOperation.DontCare, // TODO VULKAN: Only if any destination blend?
                        StoreOperation        = AttachmentStoreOperation.Store,
                        StencilLoadOperation  = AttachmentLoadOperation.DontCare,
                        StencilStoreOperation = AttachmentStoreOperation.DontCare,
                        InitialLayout         = ImageLayout.ColorAttachmentOptimal,
                        FinalLayout           = ImageLayout.ColorAttachmentOptimal,
                    };

                    colorAttachmentReferences[i] = new AttachmentReference
                    {
                        Attachment = (uint)i,
                        Layout     = ImageLayout.ColorAttachmentOptimal,
                    };
                }
            }

            if (hasDepthStencilAttachment)
            {
                attachments[attachmentCount - 1] = new AttachmentDescription
                {
                    Format                = Texture.GetFallbackDepthStencilFormat(GraphicsDevice, VulkanConvertExtensions.ConvertPixelFormat(Description.Output.DepthStencilFormat)),
                    Samples               = SampleCountFlags.Sample1,
                    LoadOperation         = AttachmentLoadOperation.Load,     // TODO VULKAN: Only if depth read enabled?
                    StoreOperation        = AttachmentStoreOperation.Store,   // TODO VULKAN: Only if depth write enabled?
                    StencilLoadOperation  = AttachmentLoadOperation.DontCare, // TODO VULKAN: Handle stencil
                    StencilStoreOperation = AttachmentStoreOperation.DontCare,
                    InitialLayout         = ImageLayout.DepthStencilAttachmentOptimal,
                    FinalLayout           = ImageLayout.DepthStencilAttachmentOptimal,
                };
            }

            var depthAttachmentReference = new AttachmentReference
            {
                Attachment = (uint)attachments.Length - 1,
                Layout     = ImageLayout.DepthStencilAttachmentOptimal,
            };

            var subpass = new SubpassDescription
            {
                PipelineBindPoint      = PipelineBindPoint.Graphics,
                ColorAttachmentCount   = (uint)renderTargetCount,
                ColorAttachments       = colorAttachmentReferences.Length > 0 ? new IntPtr(Interop.Fixed(colorAttachmentReferences)) : IntPtr.Zero,
                DepthStencilAttachment = hasDepthStencilAttachment ? new IntPtr(&depthAttachmentReference) : IntPtr.Zero,
            };

            var renderPassCreateInfo = new RenderPassCreateInfo
            {
                StructureType   = StructureType.RenderPassCreateInfo,
                AttachmentCount = (uint)attachmentCount,
                Attachments     = attachments.Length > 0 ? new IntPtr(Interop.Fixed(attachments)) : IntPtr.Zero,
                SubpassCount    = 1,
                Subpasses       = new IntPtr(&subpass)
            };

            // create pipeline layout
            // Remap descriptor set indices to those in the shader. This ordering generated by the ShaderCompiler
            var resourceGroups = Description.EffectBytecode.Reflection.ResourceBindings.Select(x => x.ResourceGroup ?? "Globals").Distinct().ToList();

            ResourceGroupCount = resourceGroups.Count;

            var layouts = Description.RootSignature.EffectDescriptorSetReflection.Layouts;

            // Get binding indices used by the shader
            var destinationBindings = Description.EffectBytecode.Stages
                                      .SelectMany(x => BinarySerialization.Read <ShaderInputBytecode>(x.Data).ResourceBindings)
                                      .GroupBy(x => x.Key, x => x.Value)
                                      .ToDictionary(x => x.Key, x => x.First());

            var maxBindingIndex    = destinationBindings.Max(x => x.Value);
            var destinationEntries = new DescriptorSetLayoutBuilder.Entry[maxBindingIndex + 1];

            DescriptorBindingMapping = new List <DescriptorSetInfo>();

            for (int i = 0; i < resourceGroups.Count; i++)
            {
                var resourceGroupName = resourceGroups[i] == "Globals" ? Description.RootSignature.EffectDescriptorSetReflection.DefaultSetSlot : resourceGroups[i];
                var layoutIndex       = resourceGroups[i] == null ? 0 : layouts.FindIndex(x => x.Name == resourceGroupName);

                // Check if the resource group is used by the shader
                if (layoutIndex == -1)
                {
                    continue;
                }

                var sourceEntries = layouts[layoutIndex].Layout.Entries;

                for (int sourceBinding = 0; sourceBinding < sourceEntries.Count; sourceBinding++)
                {
                    var sourceEntry = sourceEntries[sourceBinding];

                    int destinationBinding;
                    if (destinationBindings.TryGetValue(sourceEntry.Key.Name, out destinationBinding))
                    {
                        destinationEntries[destinationBinding] = sourceEntry;

                        // No need to umpdate immutable samplers
                        if (sourceEntry.Class == EffectParameterClass.Sampler && sourceEntry.ImmutableSampler != null)
                        {
                            continue;
                        }

                        DescriptorBindingMapping.Add(new DescriptorSetInfo
                        {
                            SourceSet          = layoutIndex,
                            SourceBinding      = sourceBinding,
                            DestinationBinding = destinationBinding,
                            DescriptorType     = VulkanConvertExtensions.ConvertDescriptorType(sourceEntry.Class, sourceEntry.Type)
                        });
                    }
                }
            }

            // Create default sampler, used by texture and buffer loads
            destinationEntries[0] = new DescriptorSetLayoutBuilder.Entry
            {
                Class            = EffectParameterClass.Sampler,
                Type             = EffectParameterType.Sampler,
                ImmutableSampler = GraphicsDevice.SamplerStates.PointWrap,
                ArraySize        = 1,
            };

            // Create descriptor set layout
            NativeDescriptorSetLayout = DescriptorSetLayout.CreateNativeDescriptorSetLayout(GraphicsDevice, destinationEntries, out DescriptorTypeCounts);

            // Create pipeline layout
            var nativeDescriptorSetLayout = NativeDescriptorSetLayout;
            var pipelineLayoutCreateInfo  = new PipelineLayoutCreateInfo
            {
                StructureType  = StructureType.PipelineLayoutCreateInfo,
                SetLayoutCount = 1,
                SetLayouts     = new IntPtr(&nativeDescriptorSetLayout)
            };

            // Create shader stages
            Dictionary <int, string> inputAttributeNames;

            // Note: important to pin this so that stages[x].Name is valid during this whole function
            void *defaultEntryPointData = Interop.Fixed(defaultEntryPoint);

            stages = CreateShaderStages(Description, out inputAttributeNames);

            var inputAttributes     = new VertexInputAttributeDescription[Description.InputElements.Length];
            int inputAttributeCount = 0;
            var inputBindings       = new VertexInputBindingDescription[inputAttributes.Length];
            int inputBindingCount   = 0;

            for (int inputElementIndex = 0; inputElementIndex < inputAttributes.Length; inputElementIndex++)
            {
                var inputElement = Description.InputElements[inputElementIndex];
                var slotIndex    = inputElement.InputSlot;

                if (inputElement.InstanceDataStepRate > 1)
                {
                    throw new NotImplementedException();
                }

                Format format;
                int    size;
                bool   isCompressed;
                VulkanConvertExtensions.ConvertPixelFormat(inputElement.Format, out format, out size, out isCompressed);

                var location = inputAttributeNames.FirstOrDefault(x => x.Value == inputElement.SemanticName && inputElement.SemanticIndex == 0 || x.Value == inputElement.SemanticName + inputElement.SemanticIndex);
                if (location.Value != null)
                {
                    inputAttributes[inputAttributeCount++] = new VertexInputAttributeDescription
                    {
                        Format   = format,
                        Offset   = (uint)inputElement.AlignedByteOffset,
                        Binding  = (uint)inputElement.InputSlot,
                        Location = (uint)location.Key
                    };
                }

                inputBindings[slotIndex].Binding   = (uint)slotIndex;
                inputBindings[slotIndex].InputRate = inputElement.InputSlotClass == InputClassification.Vertex ? VertexInputRate.Vertex : VertexInputRate.Instance;

                // TODO VULKAN: This is currently an argument to Draw() overloads.
                if (inputBindings[slotIndex].Stride < inputElement.AlignedByteOffset + size)
                {
                    inputBindings[slotIndex].Stride = (uint)(inputElement.AlignedByteOffset + size);
                }

                if (inputElement.InputSlot >= inputBindingCount)
                {
                    inputBindingCount = inputElement.InputSlot + 1;
                }
            }

            var inputAssemblyState = new PipelineInputAssemblyStateCreateInfo
            {
                StructureType          = StructureType.PipelineInputAssemblyStateCreateInfo,
                Topology               = VulkanConvertExtensions.ConvertPrimitiveType(Description.PrimitiveType),
                PrimitiveRestartEnable = VulkanConvertExtensions.ConvertPrimitiveRestart(Description.PrimitiveType),
            };

            // TODO VULKAN: Tessellation and multisampling
            var multisampleState = new PipelineMultisampleStateCreateInfo
            {
                StructureType        = StructureType.PipelineMultisampleStateCreateInfo,
                RasterizationSamples = SampleCountFlags.Sample1
            };

            //var tessellationState = new PipelineTessellationStateCreateInfo();

            var rasterizationState = new PipelineRasterizationStateCreateInfo
            {
                StructureType           = StructureType.PipelineRasterizationStateCreateInfo,
                CullMode                = VulkanConvertExtensions.ConvertCullMode(Description.RasterizerState.CullMode),
                FrontFace               = Description.RasterizerState.FrontFaceCounterClockwise ? FrontFace.CounterClockwise : FrontFace.Clockwise,
                PolygonMode             = VulkanConvertExtensions.ConvertFillMode(Description.RasterizerState.FillMode),
                DepthBiasEnable         = true, // TODO VULKAN
                DepthBiasConstantFactor = Description.RasterizerState.DepthBias,
                DepthBiasSlopeFactor    = Description.RasterizerState.SlopeScaleDepthBias,
                DepthBiasClamp          = Description.RasterizerState.DepthBiasClamp,
                LineWidth               = 1.0f,
                DepthClampEnable        = !Description.RasterizerState.DepthClipEnable,
                RasterizerDiscardEnable = false,
            };

            var depthStencilState = new PipelineDepthStencilStateCreateInfo
            {
                StructureType     = StructureType.PipelineDepthStencilStateCreateInfo,
                DepthTestEnable   = Description.DepthStencilState.DepthBufferEnable,
                StencilTestEnable = Description.DepthStencilState.StencilEnable,
                DepthWriteEnable  = Description.DepthStencilState.DepthBufferWriteEnable,

                MinDepthBounds        = 0.0f,
                MaxDepthBounds        = 1.0f,
                DepthCompareOperation = VulkanConvertExtensions.ConvertComparisonFunction(Description.DepthStencilState.DepthBufferFunction),
                Front = new StencilOperationState
                {
                    CompareOperation   = VulkanConvertExtensions.ConvertComparisonFunction(Description.DepthStencilState.FrontFace.StencilFunction),
                    DepthFailOperation = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.FrontFace.StencilDepthBufferFail),
                    FailOperation      = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.FrontFace.StencilFail),
                    PassOperation      = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.FrontFace.StencilPass),
                    CompareMask        = Description.DepthStencilState.StencilMask,
                    WriteMask          = Description.DepthStencilState.StencilWriteMask
                },
                Back = new StencilOperationState
                {
                    CompareOperation   = VulkanConvertExtensions.ConvertComparisonFunction(Description.DepthStencilState.BackFace.StencilFunction),
                    DepthFailOperation = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.BackFace.StencilDepthBufferFail),
                    FailOperation      = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.BackFace.StencilFail),
                    PassOperation      = VulkanConvertExtensions.ConvertStencilOperation(Description.DepthStencilState.BackFace.StencilPass),
                    CompareMask        = Description.DepthStencilState.StencilMask,
                    WriteMask          = Description.DepthStencilState.StencilWriteMask
                }
            };

            var description = Description.BlendState;

            var colorBlendAttachments = new PipelineColorBlendAttachmentState[renderTargetCount];

            var renderTargetBlendState = &description.RenderTarget0;

            for (int i = 0; i < renderTargetCount; i++)
            {
                colorBlendAttachments[i] = new PipelineColorBlendAttachmentState
                {
                    BlendEnable                 = renderTargetBlendState->BlendEnable,
                    AlphaBlendOperation         = VulkanConvertExtensions.ConvertBlendFunction(renderTargetBlendState->AlphaBlendFunction),
                    ColorBlendOperation         = VulkanConvertExtensions.ConvertBlendFunction(renderTargetBlendState->ColorBlendFunction),
                    DestinationAlphaBlendFactor = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->AlphaDestinationBlend),
                    DestinationColorBlendFactor = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->ColorDestinationBlend),
                    SourceAlphaBlendFactor      = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->AlphaSourceBlend),
                    SourceColorBlendFactor      = VulkanConvertExtensions.ConvertBlend(renderTargetBlendState->ColorSourceBlend),
                    ColorWriteMask              = VulkanConvertExtensions.ConvertColorWriteChannels(renderTargetBlendState->ColorWriteChannels),
                };

                if (description.IndependentBlendEnable)
                {
                    renderTargetBlendState++;
                }
            }

            var viewportState = new PipelineViewportStateCreateInfo
            {
                StructureType = StructureType.PipelineViewportStateCreateInfo,
                ScissorCount  = 1,
                ViewportCount = 1,
            };

            fixed(void *dynamicStatesPointer   = dynamicStates.Length == 0?null : dynamicStates,
                  inputAttributesPointer       = inputAttributes.Length == 0?null : inputAttributes,
                  inputBindingsPointer         = inputBindings.Length == 0?null : inputBindings,
                  colorBlendAttachmentsPointer = colorBlendAttachments.Length == 0?null : colorBlendAttachments,
                  stagesPointer = stages.Length == 0?null : stages)
            {
                var vertexInputState = new PipelineVertexInputStateCreateInfo
                {
                    StructureType = StructureType.PipelineVertexInputStateCreateInfo,
                    VertexAttributeDescriptionCount = (uint)inputAttributeCount,
                    VertexAttributeDescriptions     = (IntPtr)inputAttributesPointer,
                    VertexBindingDescriptionCount   = (uint)inputBindingCount,
                    VertexBindingDescriptions       = (IntPtr)inputBindingsPointer,
                };

                var colorBlendState = new PipelineColorBlendStateCreateInfo
                {
                    StructureType   = StructureType.PipelineColorBlendStateCreateInfo,
                    AttachmentCount = (uint)renderTargetCount,
                    Attachments     = (IntPtr)colorBlendAttachmentsPointer,
                };

                var dynamicState = new PipelineDynamicStateCreateInfo
                {
                    StructureType     = StructureType.PipelineDynamicStateCreateInfo,
                    DynamicStateCount = (uint)dynamicStates.Length,
                    DynamicStates     = (IntPtr)dynamicStatesPointer,
                };

                var createInfo = new GraphicsPipelineCreateInfo
                {
                    StructureType = StructureType.GraphicsPipelineCreateInfo,
                    StageCount    = (uint)stages.Length,
                    Stages        = (IntPtr)stagesPointer,
                    //TessellationState = new IntPtr(&tessellationState),
                    VertexInputState   = new IntPtr(&vertexInputState),
                    InputAssemblyState = new IntPtr(&inputAssemblyState),
                    RasterizationState = new IntPtr(&rasterizationState),
                    MultisampleState   = new IntPtr(&multisampleState),
                    DepthStencilState  = new IntPtr(&depthStencilState),
                    ColorBlendState    = new IntPtr(&colorBlendState),
                    DynamicState       = new IntPtr(&dynamicState),
                    ViewportState      = new IntPtr(&viewportState),
                    Subpass            = 0,
                };

                using (GraphicsDevice.QueueLock.ReadLock())
                {
                    NativeRenderPass = GraphicsDevice.NativeDevice.CreateRenderPass(ref renderPassCreateInfo);
                    NativeLayout     = GraphicsDevice.NativeDevice.CreatePipelineLayout(ref pipelineLayoutCreateInfo);

                    createInfo.Layout     = NativeLayout;
                    createInfo.RenderPass = NativeRenderPass;

                    try {
                        NativePipeline = GraphicsDevice.NativeDevice.CreateGraphicsPipelines(PipelineCache.Null, 1, &createInfo);
                    } catch (Exception e) {
                        errorDuringCreate = true;
                        NativePipeline    = Pipeline.Null;
                    }
                }
            }

            // Cleanup shader modules
            for (int i = 0; i < stages.Length; i++)
            {
                GraphicsDevice.NativeDevice.DestroyShaderModule(stages[i].Module);
            }
        }
예제 #21
0
        protected PipelineLayout CreatePipelineLayout()
        {
            var createInfo = new PipelineLayoutCreateInfo();

            return(device.CreatePipelineLayout(createInfo));
        }
예제 #22
0
        private unsafe void CreatePipelineLayout()
        {
            var binding = new DescriptorSetLayoutBinding
            {
                Binding = 0,
                DescriptorCount = 1,
                DescriptorType = DescriptorType.UniformBuffer,
                StageFlags = ShaderStageFlags.Vertex
            };

            var descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo
            {
                StructureType = StructureType.DescriptorSetLayoutCreateInfo,
                BindingCount = 1,
                Bindings = new IntPtr(&binding)
            };
            descriptorSetLayout = device.CreateDescriptorSetLayout(ref descriptorSetLayoutCreateInfo);

            var localDescriptorSetLayout = descriptorSetLayout;
            var createInfo = new PipelineLayoutCreateInfo
            {
                StructureType = StructureType.PipelineLayoutCreateInfo,
                SetLayoutCount = 1,
                SetLayouts = new IntPtr(&localDescriptorSetLayout)
            };
            pipelineLayout = device.CreatePipelineLayout(ref createInfo);

            var poolSize = new DescriptorPoolSize { DescriptorCount = 2, Type = DescriptorType.UniformBuffer };
            var descriptorPoolCreateinfo = new DescriptorPoolCreateInfo
            {
                StructureType = StructureType.DescriptorPoolCreateInfo,
                PoolSizeCount = 1,
                PoolSizes = new IntPtr(&poolSize),
                MaxSets = 2
            };
            descriptorPool = device.CreateDescriptorPool(ref descriptorPoolCreateinfo);

            var bufferCreateInfo = new BufferCreateInfo
            {
                StructureType = StructureType.BufferCreateInfo,
                Usage = BufferUsageFlags.UniformBuffer,
                Size = 64,
            };
            uniformBuffer = device.CreateBuffer(ref bufferCreateInfo);

            MemoryRequirements memoryRequirements;
            device.GetBufferMemoryRequirements(uniformBuffer, out memoryRequirements);
            var memory = AllocateMemory(MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent, memoryRequirements);

            device.BindBufferMemory(uniformBuffer, memory, 0);

            var mappedMemory = device.MapMemory(memory, 0, 64, MemoryMapFlags.None);
            var data = new[]
            {
                1.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 1.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 1.0f, 0.0f,
                0.0f, 0.0f, 0.0f, 1.0f,
            };
            Utilities.Write(mappedMemory, data, 0, data.Length);
            device.UnmapMemory(memory);
        }
예제 #23
0
        public bool Create(string vsName, string fsName,
                           VertexInputBindingDescription [] vbind,
                           VertexInputAttributeDescription [] vatts)
        {
            Device dv = mDevices.GetLogicalDevice();

            PipelineShaderStageCreateInfo plssciv = new PipelineShaderStageCreateInfo(
                ShaderStages.Vertex, mShaders[vsName], "main", null);

            PipelineShaderStageCreateInfo plsscif = new PipelineShaderStageCreateInfo(
                ShaderStages.Fragment, mShaders[fsName], "main", null);

            PipelineVertexInputStateCreateInfo plvisci = new PipelineVertexInputStateCreateInfo(
                vbind, vatts);

            PipelineInputAssemblyStateCreateInfo pliasci = new PipelineInputAssemblyStateCreateInfo(
                PrimitiveTopology.TriangleList);

            Viewport vp = new Viewport(0, 0, 1280, 720, 0f, 1f);

            Rect2D scissor = new Rect2D(Offset2D.Zero, mDevices.GetChainExtent());

            PipelineViewportStateCreateInfo plvpsci = new PipelineViewportStateCreateInfo(
                new Viewport[1] {
                vp
            }, new Rect2D[1] {
                scissor
            });

            PipelineRasterizationStateCreateInfo plrsci = new PipelineRasterizationStateCreateInfo();

            plrsci.LineWidth = 1;

            PipelineMultisampleStateCreateInfo plmssci = new PipelineMultisampleStateCreateInfo();

            plmssci.RasterizationSamples = SampleCounts.Count1;

            PipelineColorBlendAttachmentState plcbas = new PipelineColorBlendAttachmentState();

            plcbas.ColorWriteMask = ColorComponents.All;
            plcbas.BlendEnable    = false;

            PipelineColorBlendStateCreateInfo plcbsci = new PipelineColorBlendStateCreateInfo();

            plcbsci.LogicOpEnable = false;
            plcbsci.LogicOp       = LogicOp.Copy;
            plcbsci.Attachments   = new PipelineColorBlendAttachmentState[1] {
                plcbas
            };
            plcbsci.BlendConstants = ColorF4.Zero;

            PipelineLayoutCreateInfo pllci = new PipelineLayoutCreateInfo(
                mDevices.GetDSLs());

            mPipeLayout = dv.CreatePipelineLayout(pllci);

            AttachmentDescription ad = new AttachmentDescription();

            ad.Format         = Format.B8G8R8A8UNorm;
            ad.Samples        = SampleCounts.Count1;
            ad.LoadOp         = AttachmentLoadOp.Clear;
            ad.StoreOp        = AttachmentStoreOp.Store;
            ad.StencilLoadOp  = AttachmentLoadOp.DontCare;
            ad.StencilStoreOp = AttachmentStoreOp.DontCare;
            ad.InitialLayout  = ImageLayout.Undefined;
            ad.FinalLayout    = ImageLayout.PresentSrcKhr;

            AttachmentReference ar = new AttachmentReference(0, ImageLayout.ColorAttachmentOptimal);

            SubpassDescription spd = new SubpassDescription();

            spd.ColorAttachments = new AttachmentReference[1] {
                ar
            };

            SubpassDependency spdc = new SubpassDependency();

            spdc.SrcSubpass    = Constant.SubpassExternal;
            spdc.DstSubpass    = 0;
            spdc.SrcStageMask  = PipelineStages.ColorAttachmentOutput;
            spdc.SrcAccessMask = 0;
            spdc.DstStageMask  = PipelineStages.ColorAttachmentOutput;
            spdc.DstAccessMask = Accesses.ColorAttachmentRead | Accesses.ColorAttachmentWrite;


            RenderPassCreateInfo rpci = new RenderPassCreateInfo(
                new SubpassDescription[1] {
                spd
            },
                new AttachmentDescription[1] {
                ad
            },
                new SubpassDependency[1] {
                spdc
            });

            mRenderPass = dv.CreateRenderPass(rpci);

            GraphicsPipelineCreateInfo gplci = new GraphicsPipelineCreateInfo();

            gplci.Stages = new PipelineShaderStageCreateInfo[2] {
                plssciv, plsscif
            };
            gplci.VertexInputState   = plvisci;
            gplci.InputAssemblyState = pliasci;
            gplci.ViewportState      = plvpsci;
            gplci.RasterizationState = plrsci;
            gplci.MultisampleState   = plmssci;
            gplci.DepthStencilState  = null;
            gplci.ColorBlendState    = plcbsci;
            gplci.DynamicState       = null;
            gplci.Layout             = mPipeLayout;
            gplci.RenderPass         = mRenderPass;
            gplci.Subpass            = 0;
            gplci.BasePipelineHandle = null;
            gplci.BasePipelineIndex  = -1;

            mPipe = dv.CreateGraphicsPipeline(gplci);

            CreateSyncObjects();

            return(true);
        }
        private void CreateGraphicsPipeline()
        {
            // Shader stages
            var vertShaderCode = System.IO.File.ReadAllBytes("Shaders/vert.spv");
            var fragShaderCode = System.IO.File.ReadAllBytes("Shaders/frag.spv");

            var vertShaderModule = vkDevice.CreateShaderModule(vertShaderCode);
            var fragShaderModule = vkDevice.CreateShaderModule(fragShaderCode);

            var vertShaderStageInfo = new PipelineShaderStageCreateInfo()
            {
                Stage  = ShaderStageFlags.Vertex,
                Module = vertShaderModule,
                Name   = "main",
            };

            var fragShaderStageInfo = new PipelineShaderStageCreateInfo()
            {
                Stage  = ShaderStageFlags.Fragment,
                Module = fragShaderModule,
                Name   = "main",
            };

            var shaderStages = new PipelineShaderStageCreateInfo[] { vertShaderStageInfo, fragShaderStageInfo };

            // VertexInput
            var vertexInputInfo = new PipelineVertexInputStateCreateInfo()
            {
                VertexBindingDescriptionCount   = 0,
                VertexBindingDescriptions       = null,
                VertexAttributeDescriptionCount = 0,
                VertexAttributeDescriptions     = null,
            };

            var inputAssembly = new PipelineInputAssemblyStateCreateInfo()
            {
                Topology = PrimitiveTopology.TriangleList,
                PrimitiveRestartEnable = false,
            };

            var viewport = new Viewport()
            {
                X        = 0f,
                Y        = 0f,
                Width    = (float)vkSwapChainExtent.Width,
                Height   = (float)vkSwapChainExtent.Height,
                MinDepth = 0f,
                MaxDepth = 1f,
            };

            var scissor = new Rect2D()
            {
                Offset = new Offset2D()
                {
                    X = 0, Y = 0
                },
                Extent = vkSwapChainExtent,
            };

            var viewportState = new PipelineViewportStateCreateInfo()
            {
                ViewportCount = 1,
                Viewports     = new Viewport[] { viewport },
                ScissorCount  = 1,
                Scissors      = new Rect2D[] { scissor },
            };

            var rasterizer = new PipelineRasterizationStateCreateInfo()
            {
                DepthClampEnable        = false,
                RasterizerDiscardEnable = false,
                PolygonMode             = PolygonMode.Fill,
                LineWidth               = 1f,
                CullMode                = CullModeFlags.Back,
                FrontFace               = FrontFace.Clockwise,
                DepthBiasEnable         = false,
                DepthBiasConstantFactor = 0f,
                DepthBiasClamp          = 0f,
                DepthBiasSlopeFactor    = 0f,
            };

            var multisampling = new PipelineMultisampleStateCreateInfo()
            {
                SampleShadingEnable   = false,
                RasterizationSamples  = SampleCountFlags.Count1,
                MinSampleShading      = 1f,
                SampleMask            = null,
                AlphaToCoverageEnable = false,
                AlphaToOneEnable      = false,
            };

            var colorBlendAttachmend = new PipelineColorBlendAttachmentState()
            {
                ColorWriteMask = ColorComponentFlags.R | ColorComponentFlags.G | ColorComponentFlags.B | ColorComponentFlags.A,
                BlendEnable    = false,
            };

            var colorBlending = new PipelineColorBlendStateCreateInfo()
            {
                LogicOpEnable  = false,
                LogicOp        = LogicOp.Copy,
                Attachments    = new PipelineColorBlendAttachmentState[] { colorBlendAttachmend },
                BlendConstants = new float[] { 0f, 0f, 0f, 0f },
            };

            var pipelineLayoutInfo = new PipelineLayoutCreateInfo()
            {
                SetLayoutCount         = 0,
                PushConstantRangeCount = 0,
            };

            vkPipelineLayout = vkDevice.CreatePipelineLayout(pipelineLayoutInfo);

            var pipelineInfo = new GraphicsPipelineCreateInfo()
            {
                StageCount         = 2,
                Stages             = shaderStages,
                VertexInputState   = vertexInputInfo,
                InputAssemblyState = inputAssembly,
                ViewportState      = viewportState,
                RasterizationState = rasterizer,
                MultisampleState   = multisampling,
                DepthStencilState  = null,
                ColorBlendState    = colorBlending,
                DynamicState       = null,
                Layout             = vkPipelineLayout,
                RenderPass         = vkRenderPass,
                Subpass            = 0,
                BasePipelineHandle = null,
                BasePipelineIndex  = -1,
            };

            vkGraphicsPipeline = vkDevice.CreateGraphicsPipelines(null, new GraphicsPipelineCreateInfo[] { pipelineInfo })[0];
        }
        private unsafe void CreatePipelineLayout(PipelineStateDescription pipelineStateDescription)
        {
            // Remap descriptor set indices to those in the shader. This ordering generated by the ShaderCompiler
            var resourceGroups = pipelineStateDescription.EffectBytecode.Reflection.ResourceBindings.Select(x => x.ResourceGroup ?? "Globals").Distinct().ToList();
            ResourceGroupCount = resourceGroups.Count;

            var layouts = pipelineStateDescription.RootSignature.EffectDescriptorSetReflection.Layouts;
            
            // Get binding indices used by the shader
            var destinationBindings = pipelineStateDescription.EffectBytecode.Stages
                .SelectMany(x => BinarySerialization.Read<ShaderInputBytecode>(x.Data).ResourceBindings)
                .GroupBy(x => x.Key, x => x.Value)
                .ToDictionary(x => x.Key, x => x.First());

            var maxBindingIndex = destinationBindings.Max(x => x.Value);
            var destinationEntries = new DescriptorSetLayoutBuilder.Entry[maxBindingIndex + 1];

            DescriptorBindingMapping = new List<DescriptorSetInfo>();

            for (int i = 0; i < resourceGroups.Count; i++)
            {
                var resourceGroupName = resourceGroups[i] == "Globals" ? pipelineStateDescription.RootSignature.EffectDescriptorSetReflection.DefaultSetSlot : resourceGroups[i];
                var layoutIndex = resourceGroups[i] == null ? 0 : layouts.FindIndex(x => x.Name == resourceGroupName);

                // Check if the resource group is used by the shader
                if (layoutIndex == -1)
                    continue;

                var sourceEntries = layouts[layoutIndex].Layout.Entries;

                for (int sourceBinding = 0; sourceBinding < sourceEntries.Count; sourceBinding++)
                {
                    var sourceEntry = sourceEntries[sourceBinding];

                    int destinationBinding;
                    if (destinationBindings.TryGetValue(sourceEntry.Key.Name, out destinationBinding))
                    {
                        destinationEntries[destinationBinding] = sourceEntry;

                        // No need to umpdate immutable samplers
                        if (sourceEntry.Class == EffectParameterClass.Sampler && sourceEntry.ImmutableSampler != null)
                        {
                            continue;
                        }

                        DescriptorBindingMapping.Add(new DescriptorSetInfo
                        {
                            SourceSet = layoutIndex,
                            SourceBinding = sourceBinding,
                            DestinationBinding = destinationBinding,
                            DescriptorType = VulkanConvertExtensions.ConvertDescriptorType(sourceEntry.Class, sourceEntry.Type)
                        });
                    }
                }
            }

            // Create default sampler, used by texture and buffer loads
            destinationEntries[0] = new DescriptorSetLayoutBuilder.Entry
            {
                Class = EffectParameterClass.Sampler,
                Type = EffectParameterType.Sampler,
                ImmutableSampler = GraphicsDevice.SamplerStates.PointWrap,
                ArraySize = 1,
            };

            // Create descriptor set layout
            NativeDescriptorSetLayout = DescriptorSetLayout.CreateNativeDescriptorSetLayout(GraphicsDevice, destinationEntries, out DescriptorTypeCounts);

            // Create pipeline layout
            var nativeDescriptorSetLayout = NativeDescriptorSetLayout;
            var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo
            {
                StructureType = StructureType.PipelineLayoutCreateInfo,
                SetLayoutCount = 1,
                SetLayouts = new IntPtr(&nativeDescriptorSetLayout)
            };
            NativeLayout = GraphicsDevice.NativeDevice.CreatePipelineLayout(ref pipelineLayoutCreateInfo);
        }