Beispiel #1
0
 public DescriptorSet(DescriptorPool descriptorPool, params DescriptorSetLayout[] layouts)
     : this(descriptorPool) {
     foreach (DescriptorSetLayout layout in layouts)
     {
         descriptorSetLayouts.Add(layout.handle);
     }
 }
Beispiel #2
0
 public DescriptorSet(DescriptorPool descriptorPool)
 {
     pool = descriptorPool;
 }
Beispiel #3
0
        public Image generateCubeMap(Queue staggingQ, CommandPool cmdPool, CBTarget target)
        {
            const float deltaPhi   = (2.0f * (float)Math.PI) / 180.0f;
            const float deltaTheta = (0.5f * (float)Math.PI) / 64.0f;

            VkFormat format = VkFormat.R32g32b32a32Sfloat;
            uint     dim    = 64;

            if (target == CBTarget.PREFILTEREDENV)
            {
                format = VkFormat.R16g16b16a16Sfloat;
                dim    = 512;
            }

            uint numMips = (uint)Math.Floor(Math.Log(dim, 2)) + 1;

            Image imgFbOffscreen = new Image(Dev, format, VkImageUsageFlags.TransferSrc | VkImageUsageFlags.ColorAttachment,
                                             VkMemoryPropertyFlags.DeviceLocal, dim, dim);

            imgFbOffscreen.SetName("offscreenfb");
            imgFbOffscreen.CreateView();

            Image cmap = new Image(Dev, format, VkImageUsageFlags.TransferDst | VkImageUsageFlags.Sampled,
                                   VkMemoryPropertyFlags.DeviceLocal, dim, dim, VkImageType.Image2D, VkSampleCountFlags.SampleCount1, VkImageTiling.Optimal,
                                   numMips, 6, 1, VkImageCreateFlags.CubeCompatible);

            if (target == CBTarget.PREFILTEREDENV)
            {
                cmap.SetName("prefilterenvmap");
            }
            else
            {
                cmap.SetName("irradianceCube");
            }
            cmap.CreateView(VkImageViewType.Cube, VkImageAspectFlags.Color, 6, 0, numMips);
            cmap.CreateSampler(VkSamplerAddressMode.ClampToEdge);

            DescriptorPool dsPool = new DescriptorPool(Dev, 2, new VkDescriptorPoolSize(VkDescriptorType.CombinedImageSampler));

            DescriptorSetLayout dsLayout = new DescriptorSetLayout(Dev,
                                                                   new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler));


            GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault(VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount1, false);

            cfg.Layout = new PipelineLayout(Dev, dsLayout);
            cfg.Layout.AddPushConstants(
                new VkPushConstantRange(VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, (uint)Marshal.SizeOf <Matrix4x4> () + 8));

            cfg.RenderPass = new RenderPass(Dev);
            cfg.RenderPass.AddAttachment(format, VkImageLayout.ColorAttachmentOptimal);
            cfg.RenderPass.ClearValues.Add(new VkClearValue {
                color = new VkClearColorValue(0, 0, 0)
            });
            cfg.RenderPass.AddSubpass(new SubPass(VkImageLayout.ColorAttachmentOptimal));

            cfg.AddVertexBinding(0, 3 * sizeof(float));
            cfg.AddVertexAttributes(0, VkFormat.R32g32b32Sfloat);

            cfg.AddShader(VkShaderStageFlags.Vertex, "shaders/filtercube.vert.spv");
            if (target == CBTarget.PREFILTEREDENV)
            {
                cfg.AddShader(VkShaderStageFlags.Fragment, "shaders/prefilterenvmap.frag.spv");
            }
            else
            {
                cfg.AddShader(VkShaderStageFlags.Fragment, "shaders/irradiancecube.frag.spv");
            }

            Matrix4x4[] matrices =
            {
                // POSITIVE_X
                Matrix4x4.CreateRotationX(Utils.DegreesToRadians(180)) * Matrix4x4.CreateRotationY(Utils.DegreesToRadians(90)),
                // NEGATIVE_X
                Matrix4x4.CreateRotationX(Utils.DegreesToRadians(180)) * Matrix4x4.CreateRotationY(Utils.DegreesToRadians(-90)),
                // POSITIVE_Y
                Matrix4x4.CreateRotationX(Utils.DegreesToRadians(-90)),
                // NEGATIVE_Y
                Matrix4x4.CreateRotationX(Utils.DegreesToRadians(90)),
                // POSITIVE_Z
                Matrix4x4.CreateRotationX(Utils.DegreesToRadians(180)),
                // NEGATIVE_Z
                Matrix4x4.CreateRotationZ(Utils.DegreesToRadians(180))
            };

            VkImageSubresourceRange subRes = new VkImageSubresourceRange(VkImageAspectFlags.Color, 0, numMips, 0, 6);

            using (GraphicPipeline pl = new GraphicPipeline(cfg)) {
                DescriptorSet       dset     = dsPool.Allocate(dsLayout);
                DescriptorSetWrites dsUpdate = new DescriptorSetWrites(dsLayout);
                dsUpdate.Write(Dev, dset, cubemap.Descriptor);
                Dev.WaitIdle();

                using (Framebuffer fb = new Framebuffer(pl.RenderPass, dim, dim, imgFbOffscreen)) {
                    CommandBuffer cmd = cmdPool.AllocateCommandBuffer();
                    cmd.Start(VkCommandBufferUsageFlags.OneTimeSubmit);

                    cmap.SetLayout(cmd, VkImageLayout.Undefined, VkImageLayout.TransferDstOptimal, subRes);

                    float roughness = 0;

                    cmd.SetScissor(dim, dim);
                    cmd.SetViewport((float)(dim), (float)dim);

                    for (int m = 0; m < numMips; m++)
                    {
                        roughness = (float)m / ((float)numMips - 1f);

                        for (int f = 0; f < 6; f++)
                        {
                            pl.RenderPass.Begin(cmd, fb);

                            pl.Bind(cmd);

                            float viewPortSize = (float)Math.Pow(0.5, m) * dim;
                            cmd.SetViewport(viewPortSize, viewPortSize);
                            cmd.PushConstant(pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment,
                                             matrices[f] * Matrix4x4.CreatePerspectiveFieldOfView(Utils.DegreesToRadians(90), 1f, 0.1f, 512f));
                            if (target == CBTarget.IRRADIANCE)
                            {
                                cmd.PushConstant(pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, deltaPhi, (uint)Marshal.SizeOf <Matrix4x4> ());
                                cmd.PushConstant(pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, deltaTheta, (uint)Marshal.SizeOf <Matrix4x4> () + 4);
                            }
                            else
                            {
                                cmd.PushConstant(pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, roughness, (uint)Marshal.SizeOf <Matrix4x4> ());
                                cmd.PushConstant(pl.Layout, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, 64u, (uint)Marshal.SizeOf <Matrix4x4> () + 4);
                            }

                            cmd.BindDescriptorSet(pl.Layout, dset);
                            cmd.BindVertexBuffer(vboSkybox);
                            cmd.Draw(36);

                            pl.RenderPass.End(cmd);

                            imgFbOffscreen.SetLayout(cmd, VkImageAspectFlags.Color,
                                                     VkImageLayout.ColorAttachmentOptimal, VkImageLayout.TransferSrcOptimal);

                            VkImageCopy region = new VkImageCopy();
                            region.srcSubresource = new VkImageSubresourceLayers(VkImageAspectFlags.Color, 1);
                            region.dstSubresource = new VkImageSubresourceLayers(VkImageAspectFlags.Color, 1, (uint)m, (uint)f);
                            region.extent         = new VkExtent3D {
                                width = (uint)viewPortSize, height = (uint)viewPortSize, depth = 1
                            };

                            Vk.vkCmdCopyImage(cmd.Handle,
                                              imgFbOffscreen.Handle, VkImageLayout.TransferSrcOptimal,
                                              cmap.Handle, VkImageLayout.TransferDstOptimal,
                                              1, region.Pin());
                            region.Unpin();

                            imgFbOffscreen.SetLayout(cmd, VkImageAspectFlags.Color,
                                                     VkImageLayout.TransferSrcOptimal, VkImageLayout.ColorAttachmentOptimal);
                        }
                    }

                    cmap.SetLayout(cmd, VkImageLayout.TransferDstOptimal, VkImageLayout.ShaderReadOnlyOptimal, subRes);

                    cmd.End();

                    staggingQ.Submit(cmd);
                    staggingQ.WaitIdle();

                    cmd.Free();
                }
            }
            cmap.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;

            dsLayout.Dispose();
            imgFbOffscreen.Dispose();
            dsPool.Dispose();

            return(cmap);
        }
        void loadMaterials(glTFLoader ctx, DescriptorSetLayout layout, params AttachmentType[] attachments)
        {
            Model.Material[] mats = ctx.LoadMaterial();
            materials      = new Material[mats.Length];
            descriptorSets = new DescriptorSet[mats.Length];

            if (attachments.Length == 0)
            {
                throw new InvalidOperationException("At least one attachment is required for Model.WriteMaterialDescriptor");
            }

            descriptorPool = new DescriptorPool(dev, (uint)materials.Length,
                                                new VkDescriptorPoolSize(VkDescriptorType.CombinedImageSampler, (uint)(attachments.Length * materials.Length))
                                                );
            descriptorPool.SetName("descPool gltfTextures");

            for (int i = 0; i < mats.Length; i++)
            {
                materials[i] = new Material {
                    workflow        = (float)mats[i].workflow,
                    baseColorFactor = mats[i].baseColorFactor,
                    emissiveFactor  = mats[i].emissiveFactor,
                    metallicFactor  = mats[i].metallicFactor,
                    roughnessFactor = mats[i].roughnessFactor,
                    TexCoord0       = mats[i].availableAttachments,
                    TexCoord1       = mats[i].availableAttachments1,
                    alphaMask       = 0f,
                    alphaMaskCutoff = 0.0f,
                    diffuseFactor   = new Vector4(0),
                    specularFactor  = new Vector4(0)
                };

                descriptorSets[i] = descriptorPool.Allocate(layout);
                descriptorSets[i].Handle.SetDebugMarkerName(dev, "descSet " + mats[i].Name);

                VkDescriptorSetLayoutBinding dslb =
                    new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler);

                using (DescriptorSetWrites2 uboUpdate = new DescriptorSetWrites2(dev)) {
                    for (uint a = 0; a < attachments.Length; a++)
                    {
                        dslb.binding = a;
                        switch (attachments[a])
                        {
                        case AttachmentType.None:
                            break;

                        case AttachmentType.Color:
                            if (mats[i].availableAttachments.HasFlag(AttachmentType.Color))
                            {
                                uboUpdate.AddWriteInfo(descriptorSets[i], dslb, textures[(int)mats[i].baseColorTexture].Descriptor);
                            }
                            break;

                        case AttachmentType.Normal:
                            if (mats[i].availableAttachments.HasFlag(AttachmentType.Normal))
                            {
                                uboUpdate.AddWriteInfo(descriptorSets[i], dslb, textures[(int)mats[i].normalTexture].Descriptor);
                            }
                            break;

                        case AttachmentType.AmbientOcclusion:
                            if (mats[i].availableAttachments.HasFlag(AttachmentType.AmbientOcclusion))
                            {
                                uboUpdate.AddWriteInfo(descriptorSets[i], dslb, textures[(int)mats[i].occlusionTexture].Descriptor);
                            }
                            break;

                        case AttachmentType.PhysicalProps:
                            if (mats[i].availableAttachments.HasFlag(AttachmentType.PhysicalProps))
                            {
                                uboUpdate.AddWriteInfo(descriptorSets[i], dslb, textures[(int)mats[i].metallicRoughnessTexture].Descriptor);
                            }
                            break;

                        case AttachmentType.Metal:
                            break;

                        case AttachmentType.Roughness:
                            break;

                        case AttachmentType.Emissive:
                            if (mats[i].availableAttachments.HasFlag(AttachmentType.Emissive))
                            {
                                uboUpdate.AddWriteInfo(descriptorSets[i], dslb, textures[(int)mats[i].emissiveTexture].Descriptor);
                            }
                            break;
                        }
                    }
                    uboUpdate.Update();
                }
            }
        }
Beispiel #5
0
        public PBRPipeline(Queue staggingQ, RenderPass renderPass, Image uiImage, PipelineCache pipelineCache = null) :
            base(renderPass, pipelineCache, "pbr pipeline")
        {
            descriptorPool = new DescriptorPool(Dev, 2,
                                                new VkDescriptorPoolSize(VkDescriptorType.UniformBuffer, 2),
                                                new VkDescriptorPoolSize(VkDescriptorType.CombinedImageSampler, 9)
                                                );

            descLayoutMain = new DescriptorSetLayout(Dev,
                                                     new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Vertex | VkShaderStageFlags.Fragment, VkDescriptorType.UniformBuffer),
                                                     new VkDescriptorSetLayoutBinding(1, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
                                                     new VkDescriptorSetLayoutBinding(2, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
                                                     new VkDescriptorSetLayoutBinding(3, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
                                                     new VkDescriptorSetLayoutBinding(4, VkShaderStageFlags.Fragment, VkDescriptorType.UniformBuffer),
                                                     new VkDescriptorSetLayoutBinding(5, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler));//ui image

            descLayoutTextures = new DescriptorSetLayout(Dev,
                                                         new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
                                                         new VkDescriptorSetLayoutBinding(1, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
                                                         new VkDescriptorSetLayoutBinding(2, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
                                                         new VkDescriptorSetLayoutBinding(3, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler),
                                                         new VkDescriptorSetLayoutBinding(4, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler)
                                                         );

            GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault(VkPrimitiveTopology.TriangleList, renderPass.Samples);

            cfg.Layout = new PipelineLayout(Dev, descLayoutMain, descLayoutTextures);
            cfg.Layout.AddPushConstants(
                new VkPushConstantRange(VkShaderStageFlags.Vertex, (uint)Marshal.SizeOf <Matrix4x4> ()),
                new VkPushConstantRange(VkShaderStageFlags.Fragment, sizeof(int), 64)
                );
            cfg.RenderPass = renderPass;
            cfg.AddVertexBinding <PbrModel2.Vertex> (0);
            cfg.AddVertexAttributes(0, VkFormat.R32g32b32Sfloat, VkFormat.R32g32b32Sfloat, VkFormat.R32g32Sfloat, VkFormat.R32g32Sfloat);

            cfg.AddShader(VkShaderStageFlags.Vertex, "shaders/pbr.vert.spv");
            cfg.AddShader(VkShaderStageFlags.Fragment, "shaders/pbr_khr.frag.spv");

            layout = cfg.Layout;

            init(cfg);

            dsMain = descriptorPool.Allocate(descLayoutMain);

            envCube = new EnvironmentCube(dsMain, layout, staggingQ, RenderPass);

            matrices.prefilteredCubeMipLevels = envCube.prefilterCube.CreateInfo.mipLevels;
            uboMats = new HostBuffer(Dev, VkBufferUsageFlags.UniformBuffer, matrices, true);

            string[] modelPathes =
            {
                "data/models/DamagedHelmet/glTF/DamagedHelmet.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Avocado/glTF/Avocado.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/BarramundiFish/glTF/BarramundiFish.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/BoomBoxWithAxes/glTF/BoomBoxWithAxes.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Box/glTF/Box.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/EnvironmentTest/glTF/EnvironmentTest.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/MetalRoughSpheres/glTF/MetalRoughSpheres.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/OrientationTest/glTF/OrientationTest.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Buggy/glTF/Buggy.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/2CylinderEngine/glTF-Embedded/2CylinderEngine.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/FlightHelmet/glTF/FlightHelmet.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/GearboxAssy/glTF/GearboxAssy.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Lantern/glTF/Lantern.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/SciFiHelmet/glTF/SciFiHelmet.gltf",
                "/mnt/devel/vulkan/glTF-Sample-Models-master/2.0/Sponza/glTF/Sponza.gltf",
                "/mnt/devel/vkChess/data/chess.gltf"
            };


            model = new PbrModel2(staggingQ, modelPathes[0], descLayoutTextures,
                                  AttachmentType.Color,
                                  AttachmentType.PhysicalProps,
                                  AttachmentType.Normal,
                                  AttachmentType.AmbientOcclusion,
                                  AttachmentType.Emissive);
            //model = new Model (Dev, presentQueue, "../data/models/icosphere.gltf");
            //model = new Model (Dev, presentQueue, cmdPool, "../data/models/cube.gltf");
            DescriptorSetWrites uboUpdate = new DescriptorSetWrites(descLayoutMain);

            uboUpdate.Write(Dev, dsMain,
                            uboMats.Descriptor,
                            envCube.irradianceCube.Descriptor,
                            envCube.prefilterCube.Descriptor,
                            envCube.lutBrdf.Descriptor,
                            model.materialUBO.Descriptor,
                            uiImage.Descriptor);
        }