Пример #1
0
        /// <summary>
        /// Create and Activate a new frabuffer for the supplied RenderPass.
        /// </summary>
        /// <param name="_renderPass">Render pass.</param>
        /// <param name="_width">Width.</param>
        /// <param name="_height">Height.</param>
        /// <param name="views">Array of image views. If null and not in unused state, attachment image and view will be automatically created from the
        /// supplied renderpass configuration.</param>
        public FrameBuffer(RenderPass _renderPass, uint _width, uint _height, params Image[] views)
            : this(_renderPass, _width, _height)
        {
            for (int i = 0; i < views.Length; i++)
            {
                Image v = views[i];
                if (v == null)
                {
                    //automatically create attachment if not in unused state in the renderpass
                    VkAttachmentDescription ad          = renderPass.Attachments[i];
                    VkImageUsageFlags       usage       = 0;
                    VkImageAspectFlags      aspectFlags = 0;

                    Utils.QueryLayoutRequirements(ad.initialLayout, ref usage, ref aspectFlags);
                    Utils.QueryLayoutRequirements(ad.finalLayout, ref usage, ref aspectFlags);
                    foreach (SubPass sp in renderPass.SubPasses)
                    {
                        //TODO:check subpass usage
                    }

                    v = new Image(renderPass.Dev, ad.format, usage, VkMemoryPropertyFlags.DeviceLocal,
                                  _width, _height, VkImageType.Image2D, ad.samples, VkImageTiling.Optimal, 1, createInfo.layers);
                    v.SetName($"fbImg{i}");
                    v.CreateView(VkImageViewType.ImageView2D, aspectFlags);
                }
                else
                {
                    v.Activate();                     //increase ref and create handle if not already activated
                }
                attachments.Add(v);
            }
            Activate();
        }
Пример #2
0
        void initUISurface()
        {
            iFace.surf?.Dispose();
            uiImage?.Dispose();

            uiImage = new Image(dev, VkFormat.B8g8r8a8Unorm, VkImageUsageFlags.Sampled,
                                VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent, Width, Height, VkImageType.Image2D,
                                VkSampleCountFlags.SampleCount1, VkImageTiling.Linear);
            uiImage.CreateView(VkImageViewType.ImageView2D, VkImageAspectFlags.Color);
            uiImage.CreateSampler(VkFilter.Nearest, VkFilter.Nearest, VkSamplerMipmapMode.Nearest, VkSamplerAddressMode.ClampToBorder);
            uiImage.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
            uiImage.Map();

            CommandBuffer cmd = cmdPool.AllocateAndStart(VkCommandBufferUsageFlags.OneTimeSubmit);

            uiImage.SetLayout(cmd, VkImageAspectFlags.Color,
                              VkImageLayout.Undefined, VkImageLayout.ShaderReadOnlyOptimal);
            presentQueue.EndSubmitAndWait(cmd, true);

            NotifyValueChanged("uiImage", uiImage);

            uiImageUpdate?.Write(dev, uiImage.Descriptor);

            iFace.surf = new Crow.Cairo.ImageSurface(uiImage.MappedData, Crow.Cairo.Format.ARGB32,
                                                     (int)Width, (int)Height, (int)uiImage.GetSubresourceLayout().rowPitch);
        }
Пример #3
0
        //in the main vulkan thread
        void updateTextureSet()
        {
            nextTexture.CreateView(VkImageViewType.Cube, VkImageAspectFlags.Color, 6);
            nextTexture.CreateSampler();

            nextTexture.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
            DescriptorSetWrites uboUpdate = new DescriptorSetWrites(descriptorSet, dsLayout.Bindings[1]);

            uboUpdate.Write(dev, nextTexture.Descriptor);

            texture?.Dispose();
            texture     = nextTexture;
            nextTexture = null;
        }
Пример #4
0
        //in the main vulkan thread
        void updateTextureSet()
        {
            nextTexture.CreateView();
            nextTexture.CreateSampler();
            nextTexture.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;

            dev.WaitIdle();

            DescriptorSetWrites uboUpdate = new DescriptorSetWrites(descriptorSet, dsLayout.Bindings[1]);

            uboUpdate.Write(dev, nextTexture.Descriptor);

            texture?.Dispose();
            texture     = nextTexture;
            nextTexture = null;
        }
Пример #5
0
        void generateBRDFLUT(Queue staggingQ, CommandPool cmdPool)
        {
            const VkFormat format = VkFormat.R16g16Sfloat;
            const int      dim    = 512;

            lutBrdf = new Image(Dev, format, VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.Sampled,
                                VkMemoryPropertyFlags.DeviceLocal, dim, dim);
            lutBrdf.SetName("lutBrdf");

            lutBrdf.CreateView();
            lutBrdf.CreateSampler(VkSamplerAddressMode.ClampToEdge);

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

            cfg.Layout     = new PipelineLayout(Dev, new DescriptorSetLayout(Dev));
            cfg.RenderPass = new RenderPass(Dev);
            cfg.RenderPass.AddAttachment(format, VkImageLayout.ShaderReadOnlyOptimal);
            cfg.RenderPass.ClearValues.Add(new VkClearValue {
                color = new VkClearColorValue(0, 0, 0)
            });
            cfg.RenderPass.AddSubpass(new SubPass(VkImageLayout.ColorAttachmentOptimal));
            cfg.AddShader(VkShaderStageFlags.Vertex, "#deferred.genbrdflut.vert.spv");
            cfg.AddShader(VkShaderStageFlags.Fragment, "#deferred.genbrdflut.frag.spv");

            using (GraphicPipeline pl = new GraphicPipeline(cfg)) {
                using (FrameBuffer fb = new FrameBuffer(cfg.RenderPass, dim, dim, lutBrdf)) {
                    CommandBuffer cmd = cmdPool.AllocateCommandBuffer();
                    cmd.Start(VkCommandBufferUsageFlags.OneTimeSubmit);
                    pl.RenderPass.Begin(cmd, fb);
                    cmd.SetViewport(dim, dim);
                    cmd.SetScissor(dim, dim);
                    pl.Bind(cmd);
                    cmd.Draw(3, 1, 0, 0);
                    pl.RenderPass.End(cmd);
                    cmd.End();

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

                    cmd.Free();
                }
            }
            lutBrdf.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
        }
Пример #6
0
        Vector4 outlineColor = new Vector4(1.0f, 0.0f, 0.0f, 0.6f);      //alpha => 0:disabled 1:enabled

        protected override void initVulkan()
        {
            base.initVulkan();

            cmds = cmdPool.AllocateCommandBuffer(swapChain.ImageCount);

            font = new BMFont(vke.samples.Utils.GetDataFile("font.fnt"));

            vbo = new GPUBuffer <float> (dev, VkBufferUsageFlags.VertexBuffer | VkBufferUsageFlags.TransferDst, 1024);
            ibo = new GPUBuffer <ushort> (dev, VkBufferUsageFlags.IndexBuffer | VkBufferUsageFlags.TransferDst, 2048);

            descriptorPool = new DescriptorPool(dev, 1,
                                                new VkDescriptorPoolSize(VkDescriptorType.UniformBuffer),
                                                new VkDescriptorPoolSize(VkDescriptorType.CombinedImageSampler)
                                                );

            dsLayout = new DescriptorSetLayout(dev, 0,
                                               new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Vertex, VkDescriptorType.UniformBuffer),
                                               new VkDescriptorSetLayoutBinding(1, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler));

            using (GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault(VkPrimitiveTopology.TriangleList, VkSampleCountFlags.SampleCount4, false)) {
                cfg.Layout = new PipelineLayout(dev, dsLayout);
                cfg.Layout.AddPushConstants(new VkPushConstantRange(VkShaderStageFlags.Fragment, (uint)Marshal.SizeOf <Vector4> () * 2));

                cfg.RenderPass = new RenderPass(dev, swapChain.ColorFormat, cfg.Samples);

                cfg.blendAttachments[0] = new VkPipelineColorBlendAttachmentState(
                    true, VkBlendFactor.One, VkBlendFactor.OneMinusSrcAlpha, VkBlendOp.Add, VkBlendFactor.One, VkBlendFactor.Zero);

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

                cfg.AddShader(dev, VkShaderStageFlags.Vertex, "#shaders.main.vert.spv");
                cfg.AddShader(dev, VkShaderStageFlags.Fragment, "#shaders.main.frag.spv");

                pipeline = new GraphicPipeline(cfg);
            }

            uboMats = new HostBuffer(dev, VkBufferUsageFlags.UniformBuffer, matrices);
            uboMats.Map();             //permanent map

            descriptorSet = descriptorPool.Allocate(dsLayout);

            fontTexture = font.GetPageTexture(0, presentQueue, cmdPool);
            fontTexture.CreateView();
            fontTexture.CreateSampler();
            fontTexture.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;

            DescriptorSetWrites dsUpdate = new DescriptorSetWrites(descriptorSet, dsLayout);

            dsUpdate.Write(dev, uboMats.Descriptor, fontTexture.Descriptor);

            generateText("Vulkan", out HostBuffer <Vertex> staggingVbo, out HostBuffer <ushort> staggingIbo);

            PrimaryCommandBuffer cmd = cmdPool.AllocateAndStart(VkCommandBufferUsageFlags.OneTimeSubmit);

            staggingVbo.CopyTo(cmd, vbo);
            staggingIbo.CopyTo(cmd, ibo);

            presentQueue.EndSubmitAndWait(cmd);

            staggingVbo.Dispose();
            staggingIbo.Dispose();

            UpdateFrequency = 10;
        }
Пример #7
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);
            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, "#deferred.filtercube.vert.spv");
            if (target == CBTarget.PREFILTEREDENV)
            {
                cfg.AddShader(VkShaderStageFlags.Fragment, "#deferred.prefilterenvmap.frag.spv");
            }
            else
            {
                cfg.AddShader(VkShaderStageFlags.Fragment, "#deferred.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);
        }
Пример #8
0
        protected override void initVulkan()
        {
            base.initVulkan();

            imgResult = new Image(dev, VkFormat.R32g32b32a32Sfloat, VkImageUsageFlags.TransferDst | VkImageUsageFlags.Sampled, VkMemoryPropertyFlags.DeviceLocal,
                                  imgDim, imgDim);
            imgResult.CreateView();
            imgResult.CreateSampler(VkFilter.Nearest, VkFilter.Nearest, VkSamplerMipmapMode.Nearest, VkSamplerAddressMode.ClampToBorder);
            imgResult.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;

            datas = new float[data_size];

            addSeed(imgDim / 2 - 1, imgDim / 2 - 1);


            stagingDataBuff = new HostBuffer <float> (dev, VkBufferUsageFlags.TransferSrc, datas);
            stagingDataBuff.Map();

            inBuff  = new GPUBuffer <float> (dev, VkBufferUsageFlags.StorageBuffer | VkBufferUsageFlags.TransferSrc | VkBufferUsageFlags.TransferDst, (int)data_size);
            outBuff = new GPUBuffer <float> (dev, VkBufferUsageFlags.StorageBuffer | VkBufferUsageFlags.TransferSrc, (int)data_size);

            dsPool = new DescriptorPool(dev, 3,
                                        new VkDescriptorPoolSize(VkDescriptorType.CombinedImageSampler),
                                        new VkDescriptorPoolSize(VkDescriptorType.StorageBuffer, 4));
            dslImage = new DescriptorSetLayout(dev,
                                               new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler)
                                               );
            dslCompute = new DescriptorSetLayout(dev,
                                                 new VkDescriptorSetLayoutBinding(0, VkShaderStageFlags.Compute, VkDescriptorType.StorageBuffer),
                                                 new VkDescriptorSetLayoutBinding(1, VkShaderStageFlags.Compute, VkDescriptorType.StorageBuffer)
                                                 );

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

            cfg.Layout     = new PipelineLayout(dev, dslImage);
            cfg.RenderPass = new RenderPass(dev, swapChain.ColorFormat, dev.GetSuitableDepthFormat(), VkSampleCountFlags.SampleCount1);
            cfg.RenderPass.ClearValues[0] = new VkClearValue {
                color = new VkClearColorValue(0.0f, 0.1f, 0.0f)
            };

            cfg.ResetShadersAndVerticesInfos();
            cfg.AddShader(dev, VkShaderStageFlags.Vertex, "#vke.FullScreenQuad.vert.spv");
            cfg.AddShader(dev, VkShaderStageFlags.Fragment, "#shaders.simpletexture.frag.spv");

            cfg.blendAttachments[0] = new VkPipelineColorBlendAttachmentState(true);

            grPipeline = new GraphicPipeline(cfg);

            cfg.DisposeShaders();

            plCompute = new ComputePipeline(
                new PipelineLayout(dev, new VkPushConstantRange(VkShaderStageFlags.Compute, 2 * sizeof(int)), dslCompute),
                "#shaders.computeTest.comp.spv");
            plNormalize = new ComputePipeline(
                plCompute.Layout,
                "#shaders.normalize.comp.spv");

            dsImage  = dsPool.Allocate(dslImage);
            dsetPing = dsPool.Allocate(dslCompute);
            dsetPong = dsPool.Allocate(dslCompute);

            DescriptorSetWrites dsUpdate = new DescriptorSetWrites(dsetPing, dslCompute);

            dsUpdate.Write(dev, inBuff.Descriptor, outBuff.Descriptor);
            dsUpdate.Write(dev, dsetPong, outBuff.Descriptor, inBuff.Descriptor);
            dsUpdate = new DescriptorSetWrites(dsImage, dslImage);
            dsUpdate.Write(dev, imgResult.Descriptor);

            UpdateFrequency = 5;
        }