コード例 #1
0
ファイル: Sample.cs プロジェクト: jcapellman/SharpVulkan
        protected virtual void CreateCommandBuffer()
        {
            // Command pool
            var commandPoolCreateInfo = new CommandPoolCreateInfo
            {
                StructureType    = StructureType.CommandPoolCreateInfo,
                QueueFamilyIndex = 0,
                Flags            = CommandPoolCreateFlags.ResetCommandBuffer
            };

            commandPool = device.CreateCommandPool(ref commandPoolCreateInfo);

            // Command buffer
            var commandBufferAllocationInfo = new CommandBufferAllocateInfo
            {
                StructureType      = StructureType.CommandBufferAllocateInfo,
                Level              = CommandBufferLevel.Primary,
                CommandPool        = commandPool,
                CommandBufferCount = 1
            };
            CommandBuffer commandBuffer;

            device.AllocateCommandBuffers(ref commandBufferAllocationInfo, &commandBuffer);
            this.commandBuffer = commandBuffer;
        }
コード例 #2
0
ファイル: ClearViewSample.cs プロジェクト: slamj1/VulkanSharp
        CommandBuffer [] CreateCommandBuffers(Image [] images, Framebuffer [] framebuffers, RenderPass renderPass, SurfaceCapabilitiesKhr surfaceCapabilities)
        {
            var createPoolInfo = new CommandPoolCreateInfo {
                Flags = CommandPoolCreateFlags.ResetCommandBuffer
            };
            var commandPool = device.CreateCommandPool(createPoolInfo);
            var commandBufferAllocateInfo = new CommandBufferAllocateInfo {
                Level              = CommandBufferLevel.Primary,
                CommandPool        = commandPool,
                CommandBufferCount = (uint)images.Length
            };
            var buffers = device.AllocateCommandBuffers(commandBufferAllocateInfo);

            for (int i = 0; i < images.Length; i++)
            {
                var commandBufferBeginInfo = new CommandBufferBeginInfo();
                buffers [i].Begin(commandBufferBeginInfo);
                var renderPassBeginInfo = new RenderPassBeginInfo {
                    Framebuffer = framebuffers [i],
                    RenderPass  = renderPass,
                    ClearValues = new ClearValue [] { new ClearValue {
                                                          Color = new ClearColorValue(new float [] { 0.9f, 0.7f, 0.0f, 1.0f })
                                                      } },
                    RenderArea = new Rect2D {
                        Extent = surfaceCapabilities.CurrentExtent
                    }
                };
                buffers [i].CmdBeginRenderPass(renderPassBeginInfo, SubpassContents.Inline);
                buffers [i].CmdEndRenderPass();
                buffers [i].End();
            }
            return(buffers);
        }
コード例 #3
0
ファイル: Program.cs プロジェクト: iwandi/VulkanPlayground
            void InitCommandBuffers()
            {
                CommandPoolCreateInfo poolCreateInfo = new CommandPoolCreateInfo
                {
                    QueueFamilyIndex = 0,
                    Flags            = CommandPoolCreateFlags.ResetCommandBuffer,
                };

                mainCmdPool = device.CreateCommandPool(poolCreateInfo);

                CommandBufferAllocateInfo bufferAllocInfo = new CommandBufferAllocateInfo
                {
                    CommandBufferCount = 1,
                    CommandPool        = mainCmdPool,
                    Level = CommandBufferLevel.Primary,
                };

                mainCmd = device.AllocateCommandBuffers(bufferAllocInfo)[0];

                cleanupStack.Push(() => {
                    device.FreeCommandBuffer(mainCmdPool, mainCmd);
                    mainCmd = null;
                    device.DestroyCommandPool(mainCmdPool);
                    mainCmdPool = null;
                });
            }
コード例 #4
0
        private void CopyBuffer(Vulkan.Buffer srcBuffer, Vulkan.Buffer dstBuffer, DeviceSize size)
        {
            var allocInfo = new CommandBufferAllocateInfo()
            {
                CommandPool        = vkCommandPool,
                CommandBufferCount = 1,
                Level = CommandBufferLevel.Primary,
            };

            var commmandBuffer = vkDevice.AllocateCommandBuffers(allocInfo)[0];

            commmandBuffer.Begin(new CommandBufferBeginInfo()
            {
                Flags = CommandBufferUsageFlags.OneTimeSubmit
            });
            commmandBuffer.CmdCopyBuffer(srcBuffer, dstBuffer, new BufferCopy[] { new BufferCopy()
                                                                                  {
                                                                                      Size = size
                                                                                  } });
            commmandBuffer.End();

            vkGraphicsQueue.Submit(new SubmitInfo()
            {
                CommandBuffers = new CommandBuffer[] { commmandBuffer }
            });
            vkGraphicsQueue.WaitIdle();

            vkDevice.FreeCommandBuffer(vkCommandPool, commmandBuffer);
        }
コード例 #5
0
        void CreateCommandBuffer()
        {
            /*
             * We are getting closer to the end. In order to send commands to the device(GPU),
             * we must first record commands into a command buffer.
             * To allocate a command buffer, we must first create a command pool. So let us do that.
             */
            CommandPoolCreateInfo commandPoolCreateInfo = new CommandPoolCreateInfo()
            {
                Flags = 0,
                // the queue family of this command pool. All command buffers allocated from this command pool,
                // must be submitted to queues of this family ONLY.
                QueueFamilyIndex = computeQueueFamilyIndex
            };

            commandPool = device.CreateCommandPool(commandPoolCreateInfo);

            /*
             * Now allocate a command buffer from the command pool.
             */
            CommandBufferAllocateInfo commandBufferAllocateInfo = new CommandBufferAllocateInfo()
            {
                //commandBufferAllocateInfo.commandPool = commandPool; // specify the command pool to allocate from.
                // if the command buffer is primary, it can be directly submitted to queues.
                // A secondary buffer has to be called from some primary command buffer, and cannot be directly
                // submitted to a queue. To keep things simple, we use a primary command buffer.
                Level = CommandBufferLevel.Primary, // VK_COMMAND_BUFFER_LEVEL_PRIMARY;
                CommandBufferCount = 1              // allocate a single command buffer.
            };

            commandBuffers = commandPool.AllocateBuffers(commandBufferAllocateInfo); // allocate command buffer.

            /*
             * Now we shall start recording commands into the newly allocated command buffer.
             */
            CommandBufferBeginInfo beginInfo = new CommandBufferBeginInfo()
            {
                Flags = CommandBufferUsages.OneTimeSubmit// VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; // the buffer is only submitted and used once in this application.
            };

            commandBuffers[0].Begin(beginInfo); // start recording commands.

            /*
             * We need to bind a pipeline, AND a descriptor set before we dispatch.
             * The validation layer will NOT give warnings if you forget these, so be very careful not to forget them.
             */
            commandBuffers[0].CmdBindPipeline(PipelineBindPoint.Compute, pipelines[0]);                                     // VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
            commandBuffers[0].CmdBindDescriptorSets(PipelineBindPoint.Compute, pipelineLayout, 0, new[] { descriptorSet }); // VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0, 1, &descriptorSet, 0, NULL);

            /*
             * Calling vkCmdDispatch basically starts the compute pipeline, and executes the compute shader.
             * The number of workgroups is specified in the arguments.
             * If you are already familiar with compute shaders from OpenGL, this should be nothing new to you.
             */
            commandBuffers[0].CmdDispatch((int)Math.Ceiling((double)(WIDTH / WORKGROUP_SIZE)), (int)Math.Ceiling((double)(HEIGHT / WORKGROUP_SIZE)), 1);

            commandBuffers[0].End(); // end recording commands.
        }
コード例 #6
0
ファイル: Frame.cs プロジェクト: MatijaBrown/SilkyNvg
        public void CreateCommandBuffers()
        {
            CommandBufferAllocateInfo commandBufferAllocateInfo = VkInit.CommandBufferAllocateInfo(_commandPool, COMMAND_BUFFER_RESET_THRESHOLD);

            for (int i = 0; i < COMMAND_BUFFER_RESET_THRESHOLD; i++)
            {
                VkUtil.AssertVulkan(_vk.AllocateCommandBuffers(_device, commandBufferAllocateInfo, out _commandBuffers[0]));
            }
        }
コード例 #7
0
ファイル: PipeLine.cs プロジェクト: Kharzette/GrogLibsCore
        public CommandBuffer[] GimmeCommandBuffers(string queueName)
        {
            CommandBufferAllocateInfo cbai = new CommandBufferAllocateInfo();

            cbai.Level = CommandBufferLevel.Primary;
            cbai.CommandBufferCount = mChainBuffers.Length;

            CommandPool cp = mDevices.GetCommandPool(queueName);

            return(cp.AllocateBuffers(cbai));
        }
        protected override void AllocateBuffers(int v)
        {
            var commandBufferAllocateInfo = new CommandBufferAllocateInfo
            {
                Level              = CommandBufferLevel.Secondary,
                CommandPool        = this.CommandPool,
                CommandBufferCount = (uint)v
            };

            myFreeBuffers.AddRange(LogicalDevice.AllocateCommandBuffers(commandBufferAllocateInfo));
        }
コード例 #9
0
ファイル: ExampleBase.cs プロジェクト: jcoder58/Tanagra
        protected CommandBuffer[] AllocateCommandBuffers(CommandPool commandPool, uint buffersToAllocate)
        {
            var commandBufferAllocationInfo = new CommandBufferAllocateInfo(commandPool, CommandBufferLevel.Primary, buffersToAllocate);
            var commandBuffers = device.AllocateCommandBuffers(commandBufferAllocationInfo);

            if (commandBuffers.Length == 0)
            {
                throw new InvalidOperationException("Couldn't allocate any command buffers");
            }

            return(commandBuffers);
        }
コード例 #10
0
        protected override void AllocateBuffers(int v)
        {
            // var createPoolInfo = new CommandPoolCreateInfo { };
            //CommandPool = LogicalDevice.CreateCommandPool(createPoolInfo);
            var commandBufferAllocateInfo = new CommandBufferAllocateInfo
            {
                Level              = CommandBufferLevel.Primary,
                CommandPool        = this.CommandPool,
                CommandBufferCount = (uint)v
            };

            base.myFreeBuffers.AddRange(LogicalDevice.AllocateCommandBuffers(commandBufferAllocateInfo));
        }
コード例 #11
0
ファイル: Tutorial03.cs プロジェクト: Benkei/Crow.Framework
        void AllocateCommandBuffers(CommandPool pool, CommandBuffer[] command_buffers)
        {
            var command_buffer_allocate_info = new CommandBufferAllocateInfo
            {
                sType              = StructureType.CommandBufferAllocateInfo,     // VkStructureType                sType
                pNext              = IntPtr.Zero,                                 // const void                    *pNext
                commandPool        = pool,                                        // VkCommandPool                  commandPool
                level              = CommandBufferLevel.Primary,                  // VkCommandBufferLevel           level
                commandBufferCount = (uint)command_buffers.Length                 // uint32_t                       bufferCount
            };

            fixed(CommandBuffer *ptr = command_buffers)
            vk.AllocateCommandBuffers(GetDevice, ref command_buffer_allocate_info, ptr);
        }
コード例 #12
0
        public unsafe CommandBuffers(Api api, CommandPool commandPool, uint count)
        {
            (_api, _commandPool) = (api, commandPool);

            var allocInfo = new CommandBufferAllocateInfo();

            allocInfo.SType              = StructureType.CommandBufferAllocateInfo;
            allocInfo.CommandPool        = _commandPool.VkCommandPool;
            allocInfo.Level              = CommandBufferLevel.Primary;
            allocInfo.CommandBufferCount = count;

            _commandBuffers = GC.AllocateArray <CommandBuffer>((int)count, true);
            Util.Verify(_api.Vk.AllocateCommandBuffers(_api.Device.VkDevice, &allocInfo, (CommandBuffer *)Unsafe.AsPointer(ref _commandBuffers[0])), $"{nameof(CommandBuffers)}: Unable to allocate command buffers");
        }
コード例 #13
0
        protected CommandBuffer AllocateCommandBuffer(CommandBufferLevel level)
        {
            CommandBufferAllocateInfo info = new CommandBufferAllocateInfo(commandPool: this.CommandPool, level: level, commandBufferCount: 1);

            CommandBuffer buffer;

            var res = VkApi.AllocateCommandBuffers(Device, &info, &buffer);

            if (res != Result.Success)
            {
                throw new Exception("Unable to allocate command buffers");
            }

            return(buffer);
        }
コード例 #14
0
            public void Initialize(Vk api, Device device, CommandPool pool)
            {
                var allocateInfo = new CommandBufferAllocateInfo()
                {
                    SType = StructureType.CommandBufferAllocateInfo,
                    CommandBufferCount = 1,
                    CommandPool        = pool,
                    Level = CommandBufferLevel.Primary
                };

                api.AllocateCommandBuffers(device, allocateInfo, out CommandBuffer);

                Dependants   = new List <IAuto>();
                Waitables    = new HashSet <MultiFenceHolder>();
                Dependencies = new HashSet <SemaphoreHolder>();
            }
コード例 #15
0
        protected override unsafe CommandBuffer CreateObject()
        {
            // No allocator ready to be used, let's create a new one
            var commandBufferAllocationInfo = new CommandBufferAllocateInfo
            {
                StructureType      = StructureType.CommandBufferAllocateInfo,
                Level              = CommandBufferLevel.Primary,
                CommandPool        = commandPool,
                CommandBufferCount = 1,
            };

            CommandBuffer commandBuffer;

            GraphicsDevice.NativeDevice.AllocateCommandBuffers(ref commandBufferAllocationInfo, &commandBuffer);
            return(commandBuffer);
        }
コード例 #16
0
ファイル: Devices.cs プロジェクト: Kharzette/GrogLibsCore
        public void CopyBuffer(string queue,
                               string src, string dest, int size)
        {
            if (!mBuffers.ContainsKey(src))
            {
                Misc.SafeInvoke(eErrorSpam, "No buffer named: " + src + "...");
                return;
            }
            if (!mBuffers.ContainsKey(dest))
            {
                Misc.SafeInvoke(eErrorSpam, "No buffer named: " + dest + "...");
                return;
            }
            if (!mCommandPools.ContainsKey(queue))
            {
                Misc.SafeInvoke(eErrorSpam, "No pool named: " + queue + "...");
                return;
            }

            CommandBufferAllocateInfo cbai = new CommandBufferAllocateInfo();

            cbai.Level = CommandBufferLevel.Primary;
            cbai.CommandBufferCount = 1;

            CommandBuffer   [] bufs = mCommandPools[queue].AllocateBuffers(cbai);

            CommandBufferBeginInfo cbbi = new CommandBufferBeginInfo(
                CommandBufferUsages.OneTimeSubmit);

            bufs[0].Begin(cbbi);

            BufferCopy bc = new BufferCopy(size, 0, 0);

            bufs[0].CmdCopyBuffer(mBuffers[src], mBuffers[dest], bc);

            bufs[0].End();

            SubmitInfo si = new SubmitInfo();

            si.CommandBuffers = new IntPtr[] { bufs[0].Handle };

            SubmitToQueue(si, queue, null);

            mQueueNames[queue].WaitIdle();

            bufs[0].Dispose();
        }
コード例 #17
0
        private void CreateCommandBuffers()
        {
            var allocInfo = new CommandBufferAllocateInfo()
            {
                CommandPool        = vkCommandPool,
                Level              = CommandBufferLevel.Primary,
                CommandBufferCount = (uint)vkSwapChainFramebuffers.Length,
            };

            vkCommandBuffers = vkDevice.AllocateCommandBuffers(allocInfo);

            for (int i = 0; i < vkCommandBuffers.Length; i++)
            {
                var beginInfo = new CommandBufferBeginInfo()
                {
                    Flags           = CommandBufferUsageFlags.SimultaneousUse,
                    InheritanceInfo = null,
                };

                var buffer = vkCommandBuffers[i];
                buffer.Begin(beginInfo);

                var renderPassInfo = new RenderPassBeginInfo()
                {
                    RenderPass  = vkRenderPass,
                    Framebuffer = vkSwapChainFramebuffers[i],
                    RenderArea  = new Rect2D()
                    {
                        Extent = vkSwapChainExtent
                    },
                    ClearValues = new ClearValue[] { new ClearValue()
                                                     {
                                                         Color = new ClearColorValue(new float[] { 0.0f, 0.0f, 0.0f, 1.0f })
                                                     } },
                };

                buffer.CmdBeginRenderPass(renderPassInfo, SubpassContents.Inline);
                buffer.CmdBindPipeline(PipelineBindPoint.Graphics, vkGraphicsPipeline);
                buffer.CmdBindDescriptorSet(PipelineBindPoint.Graphics, vkPipelineLayout, 0, vkDescriptorSet, 0);
                buffer.CmdBindVertexBuffer(0, vkVertexBuffer, 0);
                buffer.CmdBindIndexBuffer(vkIndexBuffer, 0, IndexType.Uint16);
                buffer.CmdDrawIndexed((uint)indices.Length, 1, 0, 0, 0);
                buffer.CmdEndRenderPass();
                buffer.End();
            }
        }
コード例 #18
0
        protected CommandBuffer[] AllocateCommandBuffers(int count, CommandBufferLevel level)
        {
            CommandBufferAllocateInfo info = new CommandBufferAllocateInfo(commandPool: this.CommandPool, level: level, commandBufferCount: (uint)count);

            CommandBuffer[] buffers = new CommandBuffer[count];

            fixed(CommandBuffer *pbuffers = buffers)
            {
                var res = VkApi.AllocateCommandBuffers(Device, &info, pbuffers);

                if (res != Result.Success)
                {
                    throw new Exception("Unable to allocate command buffers");
                }
            }

            return(buffers);
        }
コード例 #19
0
ファイル: XLogoView.cs プロジェクト: iwandi/VulkanSharp
        CommandBuffer [] CreateCommandBuffers(Image [] images, Framebuffer [] framebuffers, Pipeline pipeline, Buffer vertexBuffer, Buffer indexBuffer, uint indexLength)
        {
            var createPoolInfo = new CommandPoolCreateInfo {
                Flags = CommandPoolCreateFlags.ResetCommandBuffer
            };
            var commandPool = device.CreateCommandPool(createPoolInfo);
            var commandBufferAllocateInfo = new CommandBufferAllocateInfo {
                Level              = CommandBufferLevel.Primary,
                CommandPool        = commandPool,
                CommandBufferCount = (uint)images.Length
            };
            var buffers = device.AllocateCommandBuffers(commandBufferAllocateInfo);
            var commandBufferBeginInfo = new CommandBufferBeginInfo();

            for (int i = 0; i < images.Length; i++)
            {
                buffers [i].Begin(commandBufferBeginInfo);
                var renderPassBeginInfo = new RenderPassBeginInfo {
                    Framebuffer = framebuffers [i],
                    RenderPass  = renderPass,
                    ClearValues = new ClearValue [] { new ClearValue {
                                                          Color = new ClearColorValue(new float [] { 0.9f, 0.87f, 0.75f, 1.0f })
                                                      } },
                    RenderArea = new Rect2D {
                        Extent = surfaceCapabilities.CurrentExtent
                    }
                };
                buffers [i].CmdBeginRenderPass(renderPassBeginInfo, SubpassContents.Inline);
                buffers [i].CmdBindDescriptorSets(PipelineBindPoint.Graphics, pipelineLayout, 0, descriptorSets, null);
                buffers [i].CmdBindPipeline(PipelineBindPoint.Graphics, pipeline);
                buffers [i].CmdBindVertexBuffers(0, new Buffer [] { vertexBuffer }, new DeviceSize [] { 0 });
                buffers [i].CmdBindIndexBuffer(indexBuffer, 0, IndexType.Uint16);
                buffers [i].CmdDrawIndexed(indexLength, 1, 0, 0, 0);
                buffers [i].CmdEndRenderPass();
                buffers [i].End();
            }

            return(buffers);
        }
コード例 #20
0
        static void CreateCommandBuffer()
        {
            // Command pool
            var commandPoolCreateInfo = new CommandPoolCreateInfo
            {
                QueueFamilyIndex = 0,
                Flags            = (uint)CommandPoolCreateFlags.ResetCommandBuffer,
            };

            commandPool = device.CreateCommandPool(commandPoolCreateInfo, null);
            Console.WriteLine("[ OK ] Command Pool");

            // Command Buffer
            var commandBufferAllocationInfo = new CommandBufferAllocateInfo
            {
                Level              = CommandBufferLevel.Primary,
                CommandPool        = commandPool,
                CommandBufferCount = 1,
            };

            commandBuffer = device.AllocateCommandBuffers(commandBufferAllocationInfo);
            Console.WriteLine("[ OK ] Command Buffer");
        }
コード例 #21
0
        CommandBuffer[] AllocateCommandBuffers(CommandPool commandPool, uint buffersToAllocate)
        {
            // Command buffers are objects used to record commands which can be subsequently submitted
            // to a device queue for execution. There are two levels of command buffers - primary
            // command buffers, which can execute secondary command buffers, and which are submitted to
            // queues, and secondary command buffers, which can be executed by primary command buffers,
            // and which are not directly submitted to queues.
            //
            // Recorded commands include commands to bind pipelines and descriptor sets to the command
            // buffer, commands to modify dynamic state, commands to draw (for graphics rendering),
            // commands to dispatch(for compute), commands to execute secondary command buffers (for
            // primary command buffers only), commands to copy buffers and images, and other commands.

            var commandBufferAllocationInfo = new CommandBufferAllocateInfo(commandPool, CommandBufferLevel.Primary, buffersToAllocate);
            var commandBuffers = device.AllocateCommandBuffers(commandBufferAllocationInfo);

            if (commandBuffers.Length == 0)
            {
                throw new InvalidOperationException("Couldn't allocate any command buffers");
            }

            return(commandBuffers);
        }
コード例 #22
0
ファイル: Functions.cs プロジェクト: jwollen/SharpVulkan
 public unsafe void AllocateCommandBuffers(ref CommandBufferAllocateInfo allocateInfo, CommandBuffer* commandBuffers)
 {
     fixed (CommandBufferAllocateInfo* __allocateInfo__ = &allocateInfo)
     {
         vkAllocateCommandBuffers(this, __allocateInfo__, commandBuffers).CheckError();
     }
 }
コード例 #23
0
        /// <summary>
        /// Explicitly recreate buffer with given data. Usually called after a <see cref="GraphicsDevice"/> reset.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataPointer"></param>
        public unsafe void Recreate(IntPtr dataPointer)
        {
            var createInfo = new BufferCreateInfo
            {
                StructureType = StructureType.BufferCreateInfo,
                Size = (ulong)bufferDescription.SizeInBytes,
                Flags = BufferCreateFlags.None,
            };

            createInfo.Usage |= BufferUsageFlags.TransferSource;

            // We always fill using transfer
            //if (bufferDescription.Usage != GraphicsResourceUsage.Immutable)
                createInfo.Usage |= BufferUsageFlags.TransferDestination;

            if ((ViewFlags & BufferFlags.VertexBuffer) != 0)
            {
                createInfo.Usage |= BufferUsageFlags.VertexBuffer;
                NativeAccessMask |= AccessFlags.VertexAttributeRead;
                NativePipelineStageMask |= PipelineStageFlags.VertexInput;
            }

            if ((ViewFlags & BufferFlags.IndexBuffer) != 0)
            {
                createInfo.Usage |= BufferUsageFlags.IndexBuffer;
                NativeAccessMask |= AccessFlags.IndexRead;
                NativePipelineStageMask |= PipelineStageFlags.VertexInput;
            }

            if ((ViewFlags & BufferFlags.ConstantBuffer) != 0)
            {
                createInfo.Usage |= BufferUsageFlags.UniformBuffer;
                NativeAccessMask |= AccessFlags.UniformRead;
                NativePipelineStageMask |= PipelineStageFlags.VertexShader | PipelineStageFlags.FragmentShader;
            }

            if ((ViewFlags & BufferFlags.ShaderResource) != 0)
            {
                createInfo.Usage |= BufferUsageFlags.UniformTexelBuffer;
                NativeAccessMask |= AccessFlags.ShaderRead;
                NativePipelineStageMask |= PipelineStageFlags.VertexShader | PipelineStageFlags.FragmentShader;

                if ((ViewFlags & BufferFlags.UnorderedAccess) != 0)
                {
                    createInfo.Usage |= BufferUsageFlags.StorageTexelBuffer;
                    NativeAccessMask |= AccessFlags.ShaderWrite;
                }
            }

            // Create buffer
            NativeBuffer = GraphicsDevice.NativeDevice.CreateBuffer(ref createInfo);

            // Allocate memory
            var memoryProperties = MemoryPropertyFlags.DeviceLocal;
            if (bufferDescription.Usage == GraphicsResourceUsage.Staging)
            {
                throw new NotImplementedException();
            }
            else if (Usage == GraphicsResourceUsage.Dynamic)
            {
                memoryProperties = MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent;
            }

            MemoryRequirements memoryRequirements;
            GraphicsDevice.NativeDevice.GetBufferMemoryRequirements(NativeBuffer, out memoryRequirements);

            AllocateMemory(memoryProperties, memoryRequirements);

            if (NativeMemory != DeviceMemory.Null)
            {
                GraphicsDevice.NativeDevice.BindBufferMemory(NativeBuffer, NativeMemory, 0);
            }

            if (SizeInBytes > 0)
            {
                // Begin copy command buffer
                var commandBufferAllocateInfo = new CommandBufferAllocateInfo
                {
                    StructureType = StructureType.CommandBufferAllocateInfo,
                    CommandPool = GraphicsDevice.NativeCopyCommandPool,
                    CommandBufferCount = 1,
                    Level = CommandBufferLevel.Primary
                };
                CommandBuffer commandBuffer;
                GraphicsDevice.NativeDevice.AllocateCommandBuffers(ref commandBufferAllocateInfo, &commandBuffer);
                var beginInfo = new CommandBufferBeginInfo { StructureType = StructureType.CommandBufferBeginInfo, Flags = CommandBufferUsageFlags.OneTimeSubmit };
                commandBuffer.Begin(ref beginInfo);

                // Copy to upload buffer
                if (dataPointer != IntPtr.Zero)
                {
                    if (Usage == GraphicsResourceUsage.Dynamic)
                    {
                        var uploadMemory = GraphicsDevice.NativeDevice.MapMemory(NativeMemory, 0, (ulong)SizeInBytes, MemoryMapFlags.None);
                        Utilities.CopyMemory(uploadMemory, dataPointer, SizeInBytes);
                        GraphicsDevice.NativeDevice.UnmapMemory(NativeMemory);
                    }
                    else
                    {
                        var sizeInBytes = bufferDescription.SizeInBytes;
                        SharpVulkan.Buffer uploadResource;
                        int uploadOffset;
                        var uploadMemory = GraphicsDevice.AllocateUploadBuffer(sizeInBytes, out uploadResource, out uploadOffset);

                        Utilities.CopyMemory(uploadMemory, dataPointer, sizeInBytes);

                        // Barrier
                        var memoryBarrier = new BufferMemoryBarrier(uploadResource, AccessFlags.HostWrite, AccessFlags.TransferRead, (ulong)uploadOffset, (ulong)sizeInBytes);
                        commandBuffer.PipelineBarrier(PipelineStageFlags.Host, PipelineStageFlags.Transfer, DependencyFlags.None, 0, null, 1, &memoryBarrier, 0, null);

                        // Copy
                        var bufferCopy = new BufferCopy
                        {
                            SourceOffset = (uint)uploadOffset,
                            DestinationOffset = 0,
                            Size = (uint)sizeInBytes
                        };
                        commandBuffer.CopyBuffer(uploadResource, NativeBuffer, 1, &bufferCopy);
                    }
                }
                else
                {
                    commandBuffer.FillBuffer(NativeBuffer, 0, (uint)bufferDescription.SizeInBytes, 0);
                }

                // Barrier
                var bufferMemoryBarrier = new BufferMemoryBarrier(NativeBuffer, AccessFlags.TransferWrite, NativeAccessMask);
                commandBuffer.PipelineBarrier(PipelineStageFlags.Transfer, PipelineStageFlags.AllCommands, DependencyFlags.None, 0, null, 1, &bufferMemoryBarrier, 0, null);

                // Close and submit
                commandBuffer.End();

                var submitInfo = new SubmitInfo
                {
                    StructureType = StructureType.SubmitInfo,
                    CommandBufferCount = 1,
                    CommandBuffers = new IntPtr(&commandBuffer),
                };

                lock (GraphicsDevice.QueueLock)
                {
                    GraphicsDevice.NativeCommandQueue.Submit(1, &submitInfo, Fence.Null);
                    GraphicsDevice.NativeCommandQueue.WaitIdle();
                    //commandBuffer.Reset(CommandBufferResetFlags.None);
                    GraphicsDevice.NativeDevice.FreeCommandBuffers(GraphicsDevice.NativeCopyCommandPool, 1, &commandBuffer);
                }

                InitializeViews();
            }
        }
コード例 #24
0
        /// <summary>
        /// Explicitly recreate buffer with given data. Usually called after a <see cref="GraphicsDevice"/> reset.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataPointer"></param>
        public unsafe void Recreate(IntPtr dataPointer)
        {
            var createInfo = new BufferCreateInfo
            {
                StructureType = StructureType.BufferCreateInfo,
                Size          = (ulong)bufferDescription.SizeInBytes,
                Flags         = BufferCreateFlags.None,
            };

            createInfo.Usage |= BufferUsageFlags.TransferSource;

            // We always fill using transfer
            //if (bufferDescription.Usage != GraphicsResourceUsage.Immutable)
            createInfo.Usage |= BufferUsageFlags.TransferDestination;

            if (Usage == GraphicsResourceUsage.Staging)
            {
                NativeAccessMask         = AccessFlags.HostRead | AccessFlags.HostWrite;
                NativePipelineStageMask |= PipelineStageFlags.Host;
            }
            else
            {
                if ((ViewFlags & BufferFlags.VertexBuffer) != 0)
                {
                    createInfo.Usage        |= BufferUsageFlags.VertexBuffer;
                    NativeAccessMask        |= AccessFlags.VertexAttributeRead;
                    NativePipelineStageMask |= PipelineStageFlags.VertexInput;
                }

                if ((ViewFlags & BufferFlags.IndexBuffer) != 0)
                {
                    createInfo.Usage        |= BufferUsageFlags.IndexBuffer;
                    NativeAccessMask        |= AccessFlags.IndexRead;
                    NativePipelineStageMask |= PipelineStageFlags.VertexInput;
                }

                if ((ViewFlags & BufferFlags.ConstantBuffer) != 0)
                {
                    createInfo.Usage        |= BufferUsageFlags.UniformBuffer;
                    NativeAccessMask        |= AccessFlags.UniformRead;
                    NativePipelineStageMask |= PipelineStageFlags.VertexShader | PipelineStageFlags.FragmentShader;
                }

                if ((ViewFlags & BufferFlags.ShaderResource) != 0)
                {
                    createInfo.Usage        |= BufferUsageFlags.UniformTexelBuffer;
                    NativeAccessMask        |= AccessFlags.ShaderRead;
                    NativePipelineStageMask |= PipelineStageFlags.VertexShader | PipelineStageFlags.FragmentShader;

                    if ((ViewFlags & BufferFlags.UnorderedAccess) != 0)
                    {
                        createInfo.Usage |= BufferUsageFlags.StorageTexelBuffer;
                        NativeAccessMask |= AccessFlags.ShaderWrite;
                    }
                }
            }

            // Create buffer
            NativeBuffer = GraphicsDevice.NativeDevice.CreateBuffer(ref createInfo);

            // Allocate memory
            var memoryProperties = MemoryPropertyFlags.DeviceLocal;

            if (bufferDescription.Usage == GraphicsResourceUsage.Staging || Usage == GraphicsResourceUsage.Dynamic)
            {
                memoryProperties = MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent;
            }

            MemoryRequirements memoryRequirements;

            GraphicsDevice.NativeDevice.GetBufferMemoryRequirements(NativeBuffer, out memoryRequirements);

            AllocateMemory(memoryProperties, memoryRequirements);

            if (NativeMemory != DeviceMemory.Null)
            {
                GraphicsDevice.NativeDevice.BindBufferMemory(NativeBuffer, NativeMemory, 0);
            }

            if (SizeInBytes > 0)
            {
                // Begin copy command buffer
                var commandBufferAllocateInfo = new CommandBufferAllocateInfo
                {
                    StructureType      = StructureType.CommandBufferAllocateInfo,
                    CommandPool        = GraphicsDevice.NativeCopyCommandPool,
                    CommandBufferCount = 1,
                    Level = CommandBufferLevel.Primary
                };
                CommandBuffer commandBuffer;

                lock (GraphicsDevice.QueueLock)
                {
                    GraphicsDevice.NativeDevice.AllocateCommandBuffers(ref commandBufferAllocateInfo, &commandBuffer);
                }

                var beginInfo = new CommandBufferBeginInfo {
                    StructureType = StructureType.CommandBufferBeginInfo, Flags = CommandBufferUsageFlags.OneTimeSubmit
                };
                commandBuffer.Begin(ref beginInfo);

                // Copy to upload buffer
                if (dataPointer != IntPtr.Zero)
                {
                    if (Usage == GraphicsResourceUsage.Dynamic)
                    {
                        var uploadMemory = GraphicsDevice.NativeDevice.MapMemory(NativeMemory, 0, (ulong)SizeInBytes, MemoryMapFlags.None);
                        Utilities.CopyMemory(uploadMemory, dataPointer, SizeInBytes);
                        GraphicsDevice.NativeDevice.UnmapMemory(NativeMemory);
                    }
                    else
                    {
                        var sizeInBytes = bufferDescription.SizeInBytes;
                        SharpVulkan.Buffer uploadResource;
                        int uploadOffset;
                        var uploadMemory = GraphicsDevice.AllocateUploadBuffer(sizeInBytes, out uploadResource, out uploadOffset);

                        Utilities.CopyMemory(uploadMemory, dataPointer, sizeInBytes);

                        // Barrier
                        var memoryBarrier = new BufferMemoryBarrier(uploadResource, AccessFlags.HostWrite, AccessFlags.TransferRead, (ulong)uploadOffset, (ulong)sizeInBytes);
                        commandBuffer.PipelineBarrier(PipelineStageFlags.Host, PipelineStageFlags.Transfer, DependencyFlags.None, 0, null, 1, &memoryBarrier, 0, null);

                        // Copy
                        var bufferCopy = new BufferCopy
                        {
                            SourceOffset      = (uint)uploadOffset,
                            DestinationOffset = 0,
                            Size = (uint)sizeInBytes
                        };
                        commandBuffer.CopyBuffer(uploadResource, NativeBuffer, 1, &bufferCopy);
                    }
                }
                else
                {
                    commandBuffer.FillBuffer(NativeBuffer, 0, (uint)bufferDescription.SizeInBytes, 0);
                }

                // Barrier
                var bufferMemoryBarrier = new BufferMemoryBarrier(NativeBuffer, AccessFlags.TransferWrite, NativeAccessMask);
                commandBuffer.PipelineBarrier(PipelineStageFlags.Transfer, PipelineStageFlags.AllCommands, DependencyFlags.None, 0, null, 1, &bufferMemoryBarrier, 0, null);

                // Close and submit
                commandBuffer.End();

                var submitInfo = new SubmitInfo
                {
                    StructureType      = StructureType.SubmitInfo,
                    CommandBufferCount = 1,
                    CommandBuffers     = new IntPtr(&commandBuffer),
                };

                lock (GraphicsDevice.QueueLock)
                {
                    GraphicsDevice.NativeCommandQueue.Submit(1, &submitInfo, Fence.Null);
                    GraphicsDevice.NativeCommandQueue.WaitIdle();
                    //commandBuffer.Reset(CommandBufferResetFlags.None);
                    GraphicsDevice.NativeDevice.FreeCommandBuffers(GraphicsDevice.NativeCopyCommandPool, 1, &commandBuffer);
                }

                InitializeViews();
            }
        }
コード例 #25
0
 /// <summary>
 /// Allocate command buffers from an existing command pool.
 /// </summary>
 /// <param name="allocateInfo">The structure describing parameters of the allocation.</param>
 /// <returns>
 /// The resulting command buffer objects returned. Each allocated command buffer begins in
 /// the initial state.
 /// </returns>
 /// <exception cref="VulkanException">Vulkan returns an error code.</exception>
 public CommandBuffer[] AllocateBuffers(CommandBufferAllocateInfo allocateInfo)
 {
     return(CommandBuffer.Allocate(this, &allocateInfo));
 }
コード例 #26
0
ファイル: Texture.Vulkan.cs プロジェクト: glepag1/stride
        private unsafe void InitializeImage(DataBox[] dataBoxes)
        {
            // Begin copy command buffer
            var commandBufferAllocateInfo = new CommandBufferAllocateInfo
            {
                StructureType      = StructureType.CommandBufferAllocateInfo,
                CommandPool        = GraphicsDevice.NativeCopyCommandPool,
                CommandBufferCount = 1,
                Level = CommandBufferLevel.Primary
            };
            CommandBuffer commandBuffer;

            lock (GraphicsDevice.QueueLock)
            {
                GraphicsDevice.NativeDevice.AllocateCommandBuffers(ref commandBufferAllocateInfo, &commandBuffer);
            }

            var beginInfo = new CommandBufferBeginInfo {
                StructureType = StructureType.CommandBufferBeginInfo, Flags = CommandBufferUsageFlags.OneTimeSubmit
            };

            commandBuffer.Begin(ref beginInfo);

            if (dataBoxes != null && dataBoxes.Length > 0)
            {
                // Buffer-to-image copies need to be aligned to the pixel size and 4 (always a power of 2)
                var blockSize     = Format.IsCompressed() ? NativeFormat.BlockSizeInBytes() : TexturePixelSize;
                var alignmentMask = (blockSize < 4 ? 4 : blockSize) - 1;

                int totalSize = dataBoxes.Length * alignmentMask;
                for (int i = 0; i < dataBoxes.Length; i++)
                {
                    totalSize += dataBoxes[i].SlicePitch;
                }

                SharpVulkan.Buffer uploadResource;
                int uploadOffset;
                var uploadMemory = GraphicsDevice.AllocateUploadBuffer(totalSize, out uploadResource, out uploadOffset);

                // Upload buffer barrier
                var bufferMemoryBarrier = new BufferMemoryBarrier(uploadResource, AccessFlags.HostWrite, AccessFlags.TransferRead, (ulong)uploadOffset, (ulong)totalSize);

                // Image barrier
                var initialBarrier = new ImageMemoryBarrier(NativeImage, ImageLayout.Undefined, ImageLayout.TransferDestinationOptimal, AccessFlags.None, AccessFlags.TransferWrite, new ImageSubresourceRange(NativeImageAspect));
                commandBuffer.PipelineBarrier(PipelineStageFlags.Host, PipelineStageFlags.Transfer, DependencyFlags.None, 0, null, 1, &bufferMemoryBarrier, 1, &initialBarrier);

                // Copy data boxes to upload buffer
                var copies = new BufferImageCopy[dataBoxes.Length];
                for (int i = 0; i < copies.Length; i++)
                {
                    var slicePitch = dataBoxes[i].SlicePitch;

                    int arraySlice        = i / MipLevels;
                    int mipSlice          = i % MipLevels;
                    var mipMapDescription = GetMipMapDescription(mipSlice);

                    var alignment = ((uploadOffset + alignmentMask) & ~alignmentMask) - uploadOffset;
                    uploadMemory += alignment;
                    uploadOffset += alignment;

                    Utilities.CopyMemory(uploadMemory, dataBoxes[i].DataPointer, slicePitch);

                    // TODO VULKAN: Check if pitches are valid
                    copies[i] = new BufferImageCopy
                    {
                        BufferOffset      = (ulong)uploadOffset,
                        ImageSubresource  = new ImageSubresourceLayers(ImageAspectFlags.Color, (uint)arraySlice, 1, (uint)mipSlice),
                        BufferRowLength   = 0, //(uint)(dataBoxes[i].RowPitch / pixelSize),
                        BufferImageHeight = 0, //(uint)(dataBoxes[i].SlicePitch / dataBoxes[i].RowPitch),
                        ImageOffset       = new Offset3D(0, 0, 0),
                        ImageExtent       = new Extent3D((uint)mipMapDescription.Width, (uint)mipMapDescription.Height, (uint)mipMapDescription.Depth)
                    };

                    uploadMemory += slicePitch;
                    uploadOffset += slicePitch;
                }

                // Copy from upload buffer to image
                fixed(BufferImageCopy *copiesPointer = &copies[0])
                {
                    commandBuffer.CopyBufferToImage(uploadResource, NativeImage, ImageLayout.TransferDestinationOptimal, (uint)copies.Length, copiesPointer);
                }

                IsInitialized = true;
            }

            // Transition to default layout
            var imageMemoryBarrier = new ImageMemoryBarrier(NativeImage,
                                                            dataBoxes == null || dataBoxes.Length == 0 ? ImageLayout.Undefined : ImageLayout.TransferDestinationOptimal, NativeLayout,
                                                            dataBoxes == null || dataBoxes.Length == 0 ? AccessFlags.None : AccessFlags.TransferWrite, NativeAccessMask, new ImageSubresourceRange(NativeImageAspect));

            commandBuffer.PipelineBarrier(PipelineStageFlags.Transfer, PipelineStageFlags.AllCommands, DependencyFlags.None, 0, null, 0, null, 1, &imageMemoryBarrier);

            // Close and submit
            commandBuffer.End();

            var submitInfo = new SubmitInfo
            {
                StructureType      = StructureType.SubmitInfo,
                CommandBufferCount = 1,
                CommandBuffers     = new IntPtr(&commandBuffer),
            };

            lock (GraphicsDevice.QueueLock)
            {
                GraphicsDevice.NativeCommandQueue.Submit(1, &submitInfo, Fence.Null);
                GraphicsDevice.NativeCommandQueue.WaitIdle();
                GraphicsDevice.NativeDevice.FreeCommandBuffers(GraphicsDevice.NativeCopyCommandPool, 1, &commandBuffer);
            }
        }
コード例 #27
0
ファイル: Sample.cs プロジェクト: jwollen/SharpVulkan
        private void SetImageLayout(Image image, ImageAspectFlags imageAspect, ImageLayout oldLayout, ImageLayout newLayout)
        {
            if (setupCommanBuffer == CommandBuffer.Null)
            {
                // Create command buffer
                CommandBuffer setupCommandBuffer;
                var allocateInfo = new CommandBufferAllocateInfo
                {
                    StructureType = StructureType.CommandBufferAllocateInfo,
                    CommandPool = commandPool,
                    Level = CommandBufferLevel.Primary,
                    CommandBufferCount = 1,
                };
                device.AllocateCommandBuffers(ref allocateInfo, &setupCommandBuffer);
                setupCommanBuffer = setupCommandBuffer;

                // Begin command buffer
                var inheritanceInfo = new CommandBufferInheritanceInfo { StructureType = StructureType.CommandBufferInheritanceInfo };
                var beginInfo = new CommandBufferBeginInfo
                {
                    StructureType = StructureType.CommandBufferBeginInfo,
                    InheritanceInfo = new IntPtr(&inheritanceInfo)
                };
                setupCommanBuffer.Begin(ref beginInfo);
            }

            var imageMemoryBarrier = new ImageMemoryBarrier
            {
                StructureType = StructureType.ImageMemoryBarrier,
                OldLayout = oldLayout,
                NewLayout = newLayout,
                Image = image,
                SubresourceRange = new ImageSubresourceRange(imageAspect, 0, 1, 0, 1)
            };

            switch (newLayout)
            {
                case ImageLayout.TransferDestinationOptimal:
                    imageMemoryBarrier.DestinationAccessMask = AccessFlags.TransferRead;
                    break;
                case ImageLayout.ColorAttachmentOptimal:
                    imageMemoryBarrier.DestinationAccessMask = AccessFlags.ColorAttachmentWrite;
                    break;
                case ImageLayout.DepthStencilAttachmentOptimal:
                    imageMemoryBarrier.DestinationAccessMask = AccessFlags.DepthStencilAttachmentWrite;
                    break;
                case ImageLayout.ShaderReadOnlyOptimal:
                    imageMemoryBarrier.DestinationAccessMask = AccessFlags.ShaderRead | AccessFlags.InputAttachmentRead;
                    break;
            }

            var sourceStages = PipelineStageFlags.TopOfPipe;
            var destinationStages = PipelineStageFlags.TopOfPipe;

            setupCommanBuffer.PipelineBarrier(sourceStages, destinationStages, DependencyFlags.None, 0, null, 0, null, 1, &imageMemoryBarrier);
        }
コード例 #28
0
ファイル: Sample.cs プロジェクト: jwollen/SharpVulkan
        protected virtual void CreateCommandBuffer()
        {
            // Command pool
            var commandPoolCreateInfo = new CommandPoolCreateInfo
            {
                StructureType = StructureType.CommandPoolCreateInfo,
                QueueFamilyIndex = 0,
                Flags = CommandPoolCreateFlags.ResetCommandBuffer
            };
            commandPool = device.CreateCommandPool(ref commandPoolCreateInfo);

            // Command buffer
            var commandBufferAllocationInfo = new CommandBufferAllocateInfo
            {
                StructureType = StructureType.CommandBufferAllocateInfo,
                Level = CommandBufferLevel.Primary,
                CommandPool = commandPool,
                CommandBufferCount = 1
            };
            CommandBuffer commandBuffer;
            device.AllocateCommandBuffers(ref commandBufferAllocationInfo, &commandBuffer);
            this.commandBuffer = commandBuffer;
        }
コード例 #29
0
ファイル: Sample.cs プロジェクト: jcapellman/SharpVulkan
        private void SetImageLayout(Image image, ImageAspectFlags imageAspect, ImageLayout oldLayout, ImageLayout newLayout)
        {
            if (setupCommanBuffer == CommandBuffer.Null)
            {
                // Create command buffer
                CommandBuffer setupCommandBuffer;
                var           allocateInfo = new CommandBufferAllocateInfo
                {
                    StructureType      = StructureType.CommandBufferAllocateInfo,
                    CommandPool        = commandPool,
                    Level              = CommandBufferLevel.Primary,
                    CommandBufferCount = 1,
                };
                device.AllocateCommandBuffers(ref allocateInfo, &setupCommandBuffer);
                setupCommanBuffer = setupCommandBuffer;

                // Begin command buffer
                var inheritanceInfo = new CommandBufferInheritanceInfo {
                    StructureType = StructureType.CommandBufferInheritanceInfo
                };
                var beginInfo = new CommandBufferBeginInfo
                {
                    StructureType   = StructureType.CommandBufferBeginInfo,
                    InheritanceInfo = new IntPtr(&inheritanceInfo)
                };
                setupCommanBuffer.Begin(ref beginInfo);
            }

            var imageMemoryBarrier = new ImageMemoryBarrier
            {
                StructureType    = StructureType.ImageMemoryBarrier,
                OldLayout        = oldLayout,
                NewLayout        = newLayout,
                Image            = image,
                SubresourceRange = new ImageSubresourceRange(imageAspect, 0, 1, 0, 1)
            };

            switch (newLayout)
            {
            case ImageLayout.TransferDestinationOptimal:
                imageMemoryBarrier.DestinationAccessMask = AccessFlags.TransferRead;
                break;

            case ImageLayout.ColorAttachmentOptimal:
                imageMemoryBarrier.DestinationAccessMask = AccessFlags.ColorAttachmentWrite;
                break;

            case ImageLayout.DepthStencilAttachmentOptimal:
                imageMemoryBarrier.DestinationAccessMask = AccessFlags.DepthStencilAttachmentWrite;
                break;

            case ImageLayout.ShaderReadOnlyOptimal:
                imageMemoryBarrier.DestinationAccessMask = AccessFlags.ShaderRead | AccessFlags.InputAttachmentRead;
                break;
            }

            var sourceStages      = PipelineStageFlags.TopOfPipe;
            var destinationStages = PipelineStageFlags.TopOfPipe;

            setupCommanBuffer.PipelineBarrier(sourceStages, destinationStages, DependencyFlags.None, 0, null, 0, null, 1, &imageMemoryBarrier);
        }
コード例 #30
0
ファイル: Functions.cs プロジェクト: jwollen/SharpVulkan
 internal static unsafe extern Result vkAllocateCommandBuffers(Device device, CommandBufferAllocateInfo* allocateInfo, CommandBuffer* commandBuffers);
コード例 #31
0
        /// <summary>
        ///     Initializes the specified device.
        /// </summary>
        /// <param name="graphicsProfiles">The graphics profiles.</param>
        /// <param name="deviceCreationFlags">The device creation flags.</param>
        /// <param name="windowHandle">The window handle.</param>
        private unsafe void InitializePlatformDevice(GraphicsProfile[] graphicsProfiles, DeviceCreationFlags deviceCreationFlags, object windowHandle)
        {
            if (nativeDevice != Device.Null)
            {
                // Destroy previous device
                ReleaseDevice();
            }

            rendererName = Adapter.Description;

            PhysicalDeviceProperties physicalDeviceProperties;

            NativePhysicalDevice.GetProperties(out physicalDeviceProperties);
            ConstantBufferDataPlacementAlignment = (int)physicalDeviceProperties.Limits.MinUniformBufferOffsetAlignment;

            RequestedProfile = graphicsProfiles.Last();

            var queueProperties = NativePhysicalDevice.QueueFamilyProperties;

            // Command lists are thread-safe and execute deferred
            IsDeferred = true;

            // TODO VULKAN
            // Create Vulkan device based on profile
            uint queuePriorities = 0;
            var  queueCreateInfo = new DeviceQueueCreateInfo
            {
                StructureType    = StructureType.DeviceQueueCreateInfo,
                QueueFamilyIndex = 0,
                QueueCount       = 1,
                QueuePriorities  = new IntPtr(&queuePriorities)
            };

            var enabledFeature = new PhysicalDeviceFeatures
            {
                FillModeNonSolid   = true,
                ShaderClipDistance = true,
                ShaderCullDistance = true,
                SamplerAnisotropy  = true,
                DepthClamp         = true,
            };

            var extensionProperties     = NativePhysicalDevice.GetDeviceExtensionProperties();
            var availableExtensionNames = new List <string>();
            var desiredExtensionNames   = new List <string>();

            for (int index = 0; index < extensionProperties.Length; index++)
            {
                var namePointer = new IntPtr(Interop.Fixed(ref extensionProperties[index].ExtensionName));
                var name        = Marshal.PtrToStringAnsi(namePointer);
                availableExtensionNames.Add(name);
            }

            desiredExtensionNames.Add("VK_KHR_swapchain");
            if (!availableExtensionNames.Contains("VK_KHR_swapchain"))
            {
                throw new InvalidOperationException();
            }

            if (availableExtensionNames.Contains("VK_EXT_debug_marker") && IsDebugMode)
            {
                desiredExtensionNames.Add("VK_EXT_debug_marker");
                IsProfilingSupported = true;
            }

            var enabledExtensionNames = desiredExtensionNames.Select(Marshal.StringToHGlobalAnsi).ToArray();

            try
            {
                var deviceCreateInfo = new DeviceCreateInfo
                {
                    StructureType         = StructureType.DeviceCreateInfo,
                    QueueCreateInfoCount  = 1,
                    QueueCreateInfos      = new IntPtr(&queueCreateInfo),
                    EnabledExtensionCount = (uint)enabledExtensionNames.Length,
                    EnabledExtensionNames = enabledExtensionNames.Length > 0 ? new IntPtr(Interop.Fixed(enabledExtensionNames)) : IntPtr.Zero,
                    EnabledFeatures       = new IntPtr(&enabledFeature)
                };

                nativeDevice = NativePhysicalDevice.CreateDevice(ref deviceCreateInfo);
            }
            finally
            {
                foreach (var enabledExtensionName in enabledExtensionNames)
                {
                    Marshal.FreeHGlobal(enabledExtensionName);
                }
            }

            NativeCommandQueue = nativeDevice.GetQueue(0, 0);

            //// Prepare copy command list (start it closed, so that every new use start with a Reset)
            var commandPoolCreateInfo = new CommandPoolCreateInfo
            {
                StructureType    = StructureType.CommandPoolCreateInfo,
                QueueFamilyIndex = 0, //device.NativeCommandQueue.FamilyIndex
                Flags            = CommandPoolCreateFlags.ResetCommandBuffer
            };

            NativeCopyCommandPool = NativeDevice.CreateCommandPool(ref commandPoolCreateInfo);

            var commandBufferAllocationInfo = new CommandBufferAllocateInfo
            {
                StructureType      = StructureType.CommandBufferAllocateInfo,
                Level              = CommandBufferLevel.Primary,
                CommandPool        = NativeCopyCommandPool,
                CommandBufferCount = 1
            };
            CommandBuffer nativeCommandBuffer;

            NativeDevice.AllocateCommandBuffers(ref commandBufferAllocationInfo, &nativeCommandBuffer);
            NativeCopyCommandBuffer = nativeCommandBuffer;

            DescriptorPools = new HeapPool(this);

            nativeResourceCollector       = new NativeResourceCollector(this);
            graphicsResourceLinkCollector = new GraphicsResourceLinkCollector(this);

            EmptyTexelBuffer = Buffer.Typed.New(this, 1, PixelFormat.R32G32B32A32_Float);
        }