Esempio n. 1
0
        void RenderTriangle(CommandBuffer cmdBuffer, VertexData vertexData, RenderPass renderPass, Pipeline pipeline, Framebuffer framebuffer, uint width, uint height)
        {
            // Set the viewport
            var viewport = new Viewport(0, 0, width, height, 0, 0);

            cmdBuffer.SetViewport(0, new[] { viewport });

            // Begin the render pass. Just as all commands must be issued between a Begin()
            // and End() call, certain commands can only be called bewteen BeginRenderPass()
            // and EndRenderPass()
            var renderArea      = new Rect2D(new Offset2D(0, 0), new Extent2D(width, height));
            var renderPassBegin = new RenderPassBeginInfo(renderPass, framebuffer, renderArea, null);

            cmdBuffer.BeginRenderPass(renderPassBegin, SubpassContents.Inline);
            renderPassBegin.Dispose();

            cmdBuffer.BindPipeline(PipelineBindPoint.Graphics, pipeline);

            // Render the triangle
            cmdBuffer.BindVertexBuffers(0, new[] { vertexData.Buffer }, new DeviceSize[] { 0 });
            cmdBuffer.Draw(3, 1, 0, 0);

            // End the RenderPass
            cmdBuffer.EndRenderPass();
        }
Esempio n. 2
0
        void RenderTriangle(CommandBuffer cmdBuffer, VertexData vertexData, RenderPass renderPass, Framebuffer framebuffer, Pipeline pipeline, uint width, uint height)
        {
            // Set the viewport
            var viewport = new Viewport(0, 0, width, height, 0, 0);

            cmdBuffer.SetViewport(0, new[] { viewport });

            var renderArea      = new Rect2D(new Offset2D(0, 0), new Extent2D(width, height));
            var renderPassBegin = new RenderPassBeginInfo(renderPass, framebuffer, renderArea, null);

            cmdBuffer.BeginRenderPass(renderPassBegin, SubpassContents.Inline);
            renderPassBegin.Dispose();

            cmdBuffer.BindPipeline(PipelineBindPoint.Graphics, pipeline);

            // Render the triangle
            cmdBuffer.BindVertexBuffers(0, new[] { vertexData.Buffer }, new DeviceSize[] { 0 });
            cmdBuffer.Draw(3, 1, 0, 0);

            // End the RenderPass
            cmdBuffer.EndRenderPass();
        }
Esempio n. 3
0
        void RenderTexturedQuad(CommandBuffer cmdBuffer, VertexData vertexData, ImageData imageData, PipelineLayout pipelineLayout, DescriptorSet descriptorSet, RenderPass renderPass, Pipeline pipeline, Framebuffer framebuffer, uint width, uint height)
        {
            var viewport = new Viewport(0, 0, width, height, 0, 1);

            cmdBuffer.SetViewport(0, new[] { viewport });

            var renderArea      = new Rect2D(new Offset2D(0, 0), new Extent2D(width, height));
            var renderPassBegin = new RenderPassBeginInfo(renderPass, framebuffer, renderArea, null);

            cmdBuffer.BeginRenderPass(renderPassBegin, SubpassContents.Inline);
            renderPassBegin.Dispose();

            cmdBuffer.BindDescriptorSets(PipelineBindPoint.Graphics, pipelineLayout, 0, new[] { descriptorSet }, null);

            cmdBuffer.BindPipeline(PipelineBindPoint.Graphics, pipeline);

            cmdBuffer.BindVertexBuffers(0, new[] { vertexData.Buffer }, new DeviceSize[] { 0 });
            cmdBuffer.BindIndexBuffer(vertexData.IndexBuffer, 0, IndexType.Uint32);
            cmdBuffer.DrawIndexed((uint)vertexData.Indicies.Length, 1, 0, 0, 1);

            cmdBuffer.EndRenderPass();
        }
Esempio n. 4
0
        private void DrawInternal()
        {
            // Update descriptors
            var descriptorSets = stackalloc DescriptorSet[2];
            var setLayouts     = stackalloc DescriptorSetLayout[2];

            setLayouts[0] = setLayouts[1] = descriptorSetLayout;

            var allocateInfo = new DescriptorSetAllocateInfo
            {
                StructureType      = StructureType.DescriptorSetAllocateInfo,
                DescriptorPool     = descriptorPool,
                DescriptorSetCount = 2,
                SetLayouts         = new IntPtr(setLayouts),
            };

            device.AllocateDescriptorSets(ref allocateInfo, descriptorSets);

            var bufferInfo = new DescriptorBufferInfo
            {
                Buffer = uniformBuffer,
                Range  = Vulkan.WholeSize
            };

            var write = new WriteDescriptorSet
            {
                StructureType      = StructureType.WriteDescriptorSet,
                DescriptorCount    = 1,
                DestinationSet     = descriptorSets[0],
                DestinationBinding = 0,
                DescriptorType     = DescriptorType.UniformBuffer,
                BufferInfo         = new IntPtr(&bufferInfo)
            };

            var copy = new CopyDescriptorSet
            {
                StructureType      = StructureType.CopyDescriptorSet,
                DescriptorCount    = 1,
                SourceBinding      = 0,
                DestinationBinding = 0,
                SourceSet          = descriptorSets[0],
                DestinationSet     = descriptorSets[1]
            };

            device.UpdateDescriptorSets(1, &write, 0, null);
            device.UpdateDescriptorSets(0, null, 1, &copy);

            // Post-present transition
            var memoryBarrier = new ImageMemoryBarrier
            {
                StructureType         = StructureType.ImageMemoryBarrier,
                Image                 = backBuffers[currentBackBufferIndex],
                SubresourceRange      = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1),
                OldLayout             = ImageLayout.PresentSource,
                NewLayout             = ImageLayout.ColorAttachmentOptimal,
                SourceAccessMask      = AccessFlags.MemoryRead,
                DestinationAccessMask = AccessFlags.ColorAttachmentWrite
            };

            commandBuffer.PipelineBarrier(PipelineStageFlags.TopOfPipe, PipelineStageFlags.TopOfPipe, DependencyFlags.None, 0, null, 0, null, 1, &memoryBarrier);

            // Clear render target
            var clearRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1);

            commandBuffer.ClearColorImage(backBuffers[currentBackBufferIndex], ImageLayout.TransferDestinationOptimal, new RawColor4(0, 0, 0, 1), 1, &clearRange);

            // Begin render pass
            var renderPassBeginInfo = new RenderPassBeginInfo
            {
                StructureType = StructureType.RenderPassBeginInfo,
                RenderPass    = renderPass,
                Framebuffer   = framebuffers[currentBackBufferIndex],
                RenderArea    = new Rect2D(0, 0, (uint)form.ClientSize.Width, (uint)form.ClientSize.Height),
            };

            commandBuffer.BeginRenderPass(ref renderPassBeginInfo, SubpassContents.Inline);

            // Bind pipeline
            commandBuffer.BindPipeline(PipelineBindPoint.Graphics, pipeline);

            // Bind descriptor sets
            commandBuffer.BindDescriptorSets(PipelineBindPoint.Graphics, pipelineLayout, 0, 1, descriptorSets + 1, 0, null);

            // Set viewport and scissor
            var viewport = new Viewport(0, 0, form.ClientSize.Width, form.ClientSize.Height);

            commandBuffer.SetViewport(0, 1, &viewport);

            var scissor = new Rect2D(0, 0, (uint)form.ClientSize.Width, (uint)form.ClientSize.Height);

            commandBuffer.SetScissor(0, 1, &scissor);

            // Bind vertex buffer
            var   vertexBufferCopy = vertexBuffer;
            ulong offset           = 0;

            commandBuffer.BindVertexBuffers(0, 1, &vertexBufferCopy, &offset);

            // Draw vertices
            commandBuffer.Draw(3, 1, 0, 0);

            // End render pass
            commandBuffer.EndRenderPass();

            // Pre-present transition
            memoryBarrier = new ImageMemoryBarrier
            {
                StructureType         = StructureType.ImageMemoryBarrier,
                Image                 = backBuffers[currentBackBufferIndex],
                SubresourceRange      = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1),
                OldLayout             = ImageLayout.ColorAttachmentOptimal,
                NewLayout             = ImageLayout.PresentSource,
                SourceAccessMask      = AccessFlags.ColorAttachmentWrite,
                DestinationAccessMask = AccessFlags.MemoryRead
            };
            commandBuffer.PipelineBarrier(PipelineStageFlags.AllCommands, PipelineStageFlags.BottomOfPipe, DependencyFlags.None, 0, null, 0, null, 1, &memoryBarrier);
        }
Esempio n. 5
0
        /// <summary>
        ///
        /// </summary>
        public override Task Update()
        => Task.Run(() =>
        {
            var swapchainIndexes = new Dictionary <Window, Task <uint> >();
            var cameras          = MyScene.GetComponents <Camera>();
            var lights           = MyScene.GetComponents <Light>();
            var transferCommands = new List <CommandBuffer>();

            // fetch instanced and non-instanced meshes
            var meshRenderers = (
                MyScene.GetComponents <MeshRenderer>()
                .Where(m => m.Material.Instanced == false)
                .ToArray()
                );
            _instancedMeshes.Wait();

            #region record command buffers

            _renderCommand.Begin(Vulkan.VkCommandBufferUsageFlags.OneTimeSubmit);
            _deferredCommand.Begin(Vulkan.VkCommandBufferUsageFlags.OneTimeSubmit);
            _presentCommand.Begin(Vulkan.VkCommandBufferUsageFlags.OneTimeSubmit);
            var cameraTasks = new List <Task>();
            foreach (var camera in cameras)
            {
                var window = camera.RenderTarget as Window;
                if (window != null)
                {
                    swapchainIndexes.Add(
                        window,
                        window.AcquireSwapchainImage()
                        );
                }

                // update camera descriptor sets
                camera.UpdateDescriptorSets();
                // update lighting information
                camera.UpdateLights(lights);

                #region transfer images layout

                int attachmentCount = 0;
                foreach (var attachment in camera.MrtFramebuffer.RenderPass.Attachments)
                {
                    if (attachment.Format != API.RenderPassAttachment.Default.Format)
                    {
                        continue;
                    }

                    // transfer image layout to color attachment optimial
                    // used in render command
                    _renderCommand.TransferImageLayout(
                        camera.MrtFramebuffer.Images[attachmentCount],
                        Vulkan.VkImageLayout.ColorAttachmentOptimal
                        );
                    // transfer image layout to shader read only optimal
                    // used in deffered command
                    _deferredCommand.TransferImageLayout(
                        camera.MrtFramebuffer.Images[attachmentCount],
                        Vulkan.VkImageLayout.ShaderReadOnlyOptimal
                        );
                    // transfer image layout to color attachment optimal
                    // used in deffered command
                    _presentCommand.TransferImageLayout(
                        camera.MrtFramebuffer.Images[attachmentCount],
                        Vulkan.VkImageLayout.ColorAttachmentOptimal
                        );
                    attachmentCount++;
                }

                #endregion

                #region mesh draw commands

                _renderCommand.BeginRenderPass(
                    camera.MrtFramebuffer,
                    Vulkan.VkSubpassContents.SecondaryCommandBuffers
                    );

                var secondaryDrawCommands = new List <Task <API.CommandBuffer> >();
                // non-instanced
                foreach (var meshRenderer in meshRenderers)
                {
                    // setup mesh draw command
                    secondaryDrawCommands.Add(Task.Run(() =>
                    {
                        // transfer material textures to the correct image layout
                        transferCommands.Add(meshRenderer.Material.TransferImages());
                        // update mesh render descriptor sets
                        meshRenderer.UpdateDescriptorSet();

                        return(meshRenderer.DrawCommand(
                                   camera.MrtFramebuffer,
                                   0,
                                   camera.ProjectionDescriptorSet,
                                   camera.ViewDescriptorSet,
                                   camera.Viewport,
                                   camera.Resolution
                                   ));
                    }));
                }
                foreach (var mesh in _instancedMeshes.Result)
                {
                    secondaryDrawCommands.Add(Task.Run(() =>
                    {
                        // transfer material textures to the correct image layout
                        transferCommands.Add(mesh.Key.Key.TransferImages());

                        // update instanced buffers
                        transferCommands.Add(mesh.Key.Key.UpdateInstanceBuffers(
                                                 mesh.Key.Value,
                                                 mesh.Value
                                                 ));

                        return(mesh.Key.Key.DrawInstanced(
                                   mesh.Key.Value,
                                   mesh.Value,
                                   camera.MrtFramebuffer,
                                   0,
                                   camera.ProjectionDescriptorSet,
                                   camera.ViewDescriptorSet,
                                   camera.Viewport,
                                   camera.Resolution
                                   ));
                    }));
                }
                Task.WaitAll(secondaryDrawCommands.ToArray());
                // execute all draw comands for meshes
                if (secondaryDrawCommands.Count > 0)
                {
                    _renderCommand.ExecuteCommands(secondaryDrawCommands.Select(s => s.Result).ToList());
                }

                _renderCommand.EndRenderPass();

                #endregion

                #region deffered commands

                _deferredCommand.BeginRenderPass(
                    camera.DefferedFramebuffer,
                    Vulkan.VkSubpassContents.Inline
                    );
                _deferredCommand.BindPipeline(Camera.DefferedPipeline);
                _deferredCommand.BindDescriptorSets(
                    Camera.DefferedPipeline,
                    camera.MrtDescriptorSets
                    );
                _deferredCommand.SetScissor(
                    0, 0,
                    camera.DefferedFramebuffer.Width,
                    camera.DefferedFramebuffer.Height
                    );
                _deferredCommand.SetViewport(
                    0, 0,
                    camera.DefferedFramebuffer.Width,
                    camera.DefferedFramebuffer.Height
                    );
                _deferredCommand.Draw(6, 1);
                _deferredCommand.EndRenderPass();

                #endregion

                #region update render targets

                if (camera.RenderTarget != null)
                {
                    _presentCommand.TransferImageLayout(
                        camera.DefferedFramebuffer.Images[0],
                        Vulkan.VkImageLayout.TransferSrcOptimal
                        );
                    _presentCommand.TransferImageLayout(
                        camera.RenderTarget.RenderedImage,
                        Vulkan.VkImageLayout.TransferDstOptimal
                        );
                    // copy image from camera framebuffer to render target
                    _presentCommand.BlitImage(
                        camera.DefferedFramebuffer.Images[0].Handle,
                        camera.DefferedFramebuffer.Images[0].Format,
                        camera.DefferedFramebuffer.Images[0].Layout.First(),
                        0, 0,
                        (int)camera.DefferedFramebuffer.Width,
                        (int)camera.DefferedFramebuffer.Height,
                        0,
                        camera.RenderTarget.RenderedImage.Handle,
                        camera.RenderTarget.RenderedImage.Format,
                        camera.RenderTarget.RenderedImage.Layout.First(),
                        0, 0,
                        (int)camera.RenderTarget.RenderedImage.Width,
                        (int)camera.RenderTarget.RenderedImage.Height,
                        0
                        );
                }

                #endregion
            }
            _renderCommand.End();
            _deferredCommand.End();

            #endregion

            #region submit commands

            var transformCommandSemaphores = new List <Semaphore>();
            transferCommands = transferCommands.Where(t => t != null).ToList();
            if (transferCommands.Count > 0)
            {
                // submit transfer command
                _module.CommandBufferService.Submit(
                    transferCommands,
                    new List <Semaphore> {
                    _transferCommandSemaphore
                }
                    );
                transformCommandSemaphores.Add(_transferCommandSemaphore);
            }
            // submit render commnad
            _module.CommandBufferService.Submit(
                _renderCommand,
                new List <Semaphore> {
                _renderCommandSemaphore
            },
                transformCommandSemaphores
                );
            // submit deffered command
            _module.CommandBufferService.Submit(
                _deferredCommand,
                new List <Semaphore> {
                _defferedCommandSemaphore
            },
                new List <Semaphore> {
                _renderCommandSemaphore
            }
                );

            #endregion

            #region update render targets

            foreach (var swapchain in swapchainIndexes)
            {
                swapchain.Value.Wait();
                var swapchainIndex = (int)swapchain.Value.Result;
                var window         = swapchain.Key;
                _presentCommand.TransferImageLayout(
                    window.RenderedImage,
                    Vulkan.VkImageLayout.TransferSrcOptimal
                    );
                _presentCommand.TransferImageLayout(
                    window.Swapchain.Images[swapchainIndex],
                    Vulkan.VkImageLayout.TransferDstOptimal
                    );
                _presentCommand.BlitImage(
                    window.RenderedImage.Handle,
                    window.RenderedImage.Format,
                    window.RenderedImage.Layout.First(),
                    0, 0,
                    (int)window.RenderedImage.Width,
                    (int)window.RenderedImage.Height,
                    0,
                    window.Swapchain.Images[swapchainIndex].Handle,
                    window.Swapchain.Images[swapchainIndex].Format,
                    window.Swapchain.Images[swapchainIndex].Layout.First(),
                    0, 0,
                    (int)window.Swapchain.SurfaceExtent.width,
                    (int)window.Swapchain.SurfaceExtent.height,
                    0
                    );
                _presentCommand.TransferImageLayout(
                    window.Swapchain.Images[swapchainIndex],
                    Vulkan.VkImageLayout.PresentSrcKHR
                    );
            }

            _presentCommand.End();

            _module.CommandBufferService.Submit(
                _presentCommand,
                new List <Semaphore> {
                _presentCommandSemaphore
            },
                new List <Semaphore> {
                _defferedCommandSemaphore
            }
                );

            #endregion

            #region update swapchain

            foreach (var swapchain in swapchainIndexes)
            {
                var window = swapchain.Key;
                _module.CommandBufferService.Present(
                    window.Swapchain,
                    swapchain.Value.Result,
                    new List <Semaphore> {
                    _presentCommandSemaphore
                }
                    );
            }

            #endregion
        });
Esempio n. 6
0
        public override void Bind(Device device, RenderPass renderPass, CommandBuffer commandBuffer, Extent2D targetExtent)
        {
            this.aspectRatio = (float)targetExtent.Width / (float)targetExtent.Height;

            this.pipeline = device.CreateGraphicsPipelines(null, new[]
            {
                new GraphicsPipelineCreateInfo
                {
                    Layout           = this.pipelineLayout,
                    RenderPass       = renderPass,
                    Subpass          = 0,
                    VertexInputState = new PipelineVertexInputStateCreateInfo()
                    {
                        VertexBindingDescriptions   = new [] { Vertex.GetBindingDescription() },
                        VertexAttributeDescriptions = Vertex.GetAttributeDescriptions()
                    },
                    InputAssemblyState = new PipelineInputAssemblyStateCreateInfo
                    {
                        PrimitiveRestartEnable = false,
                        Topology = PrimitiveTopology.TriangleList
                    },
                    ViewportState = new PipelineViewportStateCreateInfo
                    {
                        Viewports = new[]
                        {
                            new Viewport
                            {
                                X        = 0f,
                                Y        = 0f,
                                Width    = targetExtent.Width,
                                Height   = targetExtent.Height,
                                MaxDepth = 1,
                                MinDepth = 0
                            }
                        },
                        Scissors = new[]
                        {
                            new Rect2D
                            {
                                Offset = new Offset2D(),
                                Extent = targetExtent
                            }
                        }
                    },
                    RasterizationState = new PipelineRasterizationStateCreateInfo
                    {
                        DepthClampEnable        = false,
                        RasterizerDiscardEnable = false,
                        PolygonMode             = PolygonMode.Fill,
                        LineWidth       = 1,
                        CullMode        = CullModeFlags.Back,
                        FrontFace       = FrontFace.CounterClockwise,
                        DepthBiasEnable = false
                    },
                    MultisampleState = new PipelineMultisampleStateCreateInfo
                    {
                        SampleShadingEnable  = false,
                        RasterizationSamples = SampleCountFlags.SampleCount1,
                        MinSampleShading     = 1
                    },
                    ColorBlendState = new PipelineColorBlendStateCreateInfo
                    {
                        Attachments = new[]
                        {
                            new PipelineColorBlendAttachmentState
                            {
                                ColorWriteMask = ColorComponentFlags.R
                                                 | ColorComponentFlags.G
                                                 | ColorComponentFlags.B
                                                 | ColorComponentFlags.A,
                                BlendEnable                 = false,
                                SourceColorBlendFactor      = BlendFactor.One,
                                DestinationColorBlendFactor = BlendFactor.Zero,
                                ColorBlendOp                = BlendOp.Add,
                                SourceAlphaBlendFactor      = BlendFactor.One,
                                DestinationAlphaBlendFactor = BlendFactor.Zero,
                                AlphaBlendOp                = BlendOp.Add
                            }
                        },
                        LogicOpEnable  = false,
                        LogicOp        = LogicOp.Copy,
                        BlendConstants = new float[] { 0, 0, 0, 0 }
                    },
                    DepthStencilState = new PipelineDepthStencilStateCreateInfo
                    {
                        DepthTestEnable       = true,
                        DepthWriteEnable      = true,
                        DepthCompareOp        = CompareOp.Less,
                        DepthBoundsTestEnable = false,
                        MinDepthBounds        = 0,
                        MaxDepthBounds        = 1,
                        StencilTestEnable     = false
                    },
                    Stages = new[]
                    {
                        new PipelineShaderStageCreateInfo
                        {
                            Stage  = ShaderStageFlags.Vertex,
                            Module = this.vertexShader,
                            Name   = "main"
                        },
                        new PipelineShaderStageCreateInfo
                        {
                            Stage  = ShaderStageFlags.Fragment,
                            Module = this.fragmentShader,
                            Name   = "main"
                        }
                    }
                }
            }).Single();

            commandBuffer.BindPipeline(PipelineBindPoint.Graphics, this.pipeline);

            commandBuffer.BindVertexBuffers(0, this.vertexBuffer.Buffer, (DeviceSize)0);

            commandBuffer.BindIndexBuffer(this.indexBuffer.Buffer, 0, IndexType.UInt32);

            commandBuffer.BindDescriptorSets(PipelineBindPoint.Graphics, pipelineLayout, 0, descriptorSet, null);

            commandBuffer.DrawIndexed((uint)indexCount, 1, 0, 0, 0);
        }
Esempio n. 7
0
        public override void Bind(Device device, RenderPass renderPass, CommandBuffer commandBuffer, Extent2D targetExtent)
        {
            this.aspectRatio = (float)targetExtent.Width / (float)targetExtent.Height;

            this.projectionMatrix = mat4.Translate(0, -1, 0) * mat4.Scale(256f / targetExtent.Width, 256f / targetExtent.Height, 1);

            this.renderStateBuffer.Update(new RenderState {
                Projection = mat4.Identity, View = mat4.Identity
            });

            this.pipeline = device.CreateGraphicsPipeline(null,
                                                          new[]
            {
                new PipelineShaderStageCreateInfo
                {
                    Stage  = ShaderStageFlags.Vertex,
                    Module = this.vertexShader,
                    Name   = "main"
                },
                new PipelineShaderStageCreateInfo
                {
                    Stage  = ShaderStageFlags.Fragment,
                    Module = this.fragmentShader,
                    Name   = "main"
                }
            },
                                                          new PipelineVertexInputStateCreateInfo()
            {
                VertexBindingDescriptions   = new[] { Vertex.GetBindingDescription(), SpriteData.GetBindingDescription() },
                VertexAttributeDescriptions = Vertex.GetAttributeDescriptions().Concat(SpriteData.GetAttributeDescriptions()).ToArray()
            },
                                                          new PipelineInputAssemblyStateCreateInfo
            {
                Topology = PrimitiveTopology.TriangleList
            },
                                                          new PipelineRasterizationStateCreateInfo
            {
                PolygonMode = PolygonMode.Fill,
                LineWidth   = 1,
                CullMode    = CullModeFlags.Back,
                FrontFace   = FrontFace.CounterClockwise
            },
                                                          this.pipelineLayout,
                                                          renderPass,
                                                          0,
                                                          null,
                                                          0,
                                                          viewportState: new PipelineViewportStateCreateInfo
            {
                Viewports = new[]
                {
                    new Viewport
                    {
                        X        = 0f,
                        Y        = 0f,
                        Width    = targetExtent.Width,
                        Height   = targetExtent.Height,
                        MaxDepth = 1,
                        MinDepth = 0
                    }
                },
                Scissors = new[]
                {
                    new Rect2D(targetExtent)
                }
            },
                                                          multisampleState: new PipelineMultisampleStateCreateInfo
            {
                SampleShadingEnable  = false,
                RasterizationSamples = SampleCountFlags.SampleCount1,
                MinSampleShading     = 1
            },
                                                          depthStencilState: new PipelineDepthStencilStateCreateInfo
            {
                DepthTestEnable  = false,
                DepthWriteEnable = true,
                DepthCompareOp   = CompareOp.Less,
                MinDepthBounds   = 0,
                MaxDepthBounds   = 1
            },
                                                          colorBlendState: new PipelineColorBlendStateCreateInfo
            {
                Attachments = new[]
                {
                    new PipelineColorBlendAttachmentState
                    {
                        ColorWriteMask = ColorComponentFlags.R
                                         | ColorComponentFlags.G
                                         | ColorComponentFlags.B
                                         | ColorComponentFlags.A,
                        BlendEnable                 = true,
                        SourceColorBlendFactor      = BlendFactor.SourceAlpha,
                        DestinationColorBlendFactor = BlendFactor.OneMinusSourceAlpha,
                        ColorBlendOp                = BlendOp.Add,
                        SourceAlphaBlendFactor      = BlendFactor.One,
                        DestinationAlphaBlendFactor = BlendFactor.One,
                        AlphaBlendOp                = BlendOp.Max
                    }
                },
                BlendConstants = new float[] { 0, 0, 0, 0 }
            });

            commandBuffer.BindPipeline(PipelineBindPoint.Graphics, this.pipeline);

            commandBuffer.BindVertexBuffers(0, new[] { this.vertexBuffer.Buffer, this.spriteDataBuffer.Buffer }, new DeviceSize[] { 0, 0 });

            commandBuffer.BindIndexBuffer(this.indexBuffer.Buffer, 0, IndexType.Uint32);

            commandBuffer.BindDescriptorSets(PipelineBindPoint.Graphics, pipelineLayout, 0, this.descriptorSet, null);

            commandBuffer.DrawIndexedIndirect(this.indirectCommandBuffer.Buffer, 0, 1, 0);
        }