Ejemplo n.º 1
0
        void Render(Queue queue, CommandPool cmdPool, VertexData vertexData, ImageData imageData, Buffer imageBuffer, RenderPass renderPass, Pipeline pipeline, Framebuffer framebuffer)
        {
            uint width  = imageData.Width;
            uint height = imageData.Height;

            var cmdBuffers = AllocateCommandBuffers(cmdPool, 1);
            var cmdBuffer  = cmdBuffers[0];

            var beginInfo = new CommandBufferBeginInfo();

            cmdBuffer.Begin(beginInfo);  // CommandBuffer Begin

            PipelineBarrierSetLayout(cmdBuffer, imageData.Image, ImageLayout.Preinitialized, ImageLayout.ColorAttachmentOptimal, AccessFlags.HostWrite, AccessFlags.ColorAttachmentWrite);

            var clearRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1);

            cmdBuffer.ClearColorImage(imageData.Image, ImageLayout.TransferDstOptimal, new ClearColorValue(), new[] { clearRange });

            RenderTriangle(cmdBuffer, vertexData, renderPass, pipeline, framebuffer, width, height);

            // Prepare the render target for copying
            PipelineBarrierSetLayout(cmdBuffer, imageData.Image, ImageLayout.ColorAttachmentOptimal, ImageLayout.TransferSrcOptimal, AccessFlags.ColorAttachmentWrite, AccessFlags.TransferRead);

            // Copy the render target image to a buffer
            CopyImageToBuffer(cmdBuffer, imageData, imageBuffer, width, height);

            // End recording commands to the buffer
            cmdBuffer.End();

            SubmitForExecution(queue, cmdBuffer);

            queue.WaitIdle(); // wait for execution to finish

            device.FreeCommandBuffers(cmdPool, new[] { cmdBuffer });
        }
Ejemplo n.º 2
0
        void CopyBufferToImage(Queue queue, CommandPool cmdPool, ImageData imageData, Buffer imageBuffer)
        {
            var cmdBuffers = AllocateCommandBuffers(cmdPool, 1);
            var cmdBuffer  = cmdBuffers[0];

            var beginInfo = new CommandBufferBeginInfo();

            cmdBuffer.Begin(beginInfo);

            PipelineBarrierSetLayout(cmdBuffer, imageData.Image, ImageLayout.Preinitialized, ImageLayout.TransferDstOptimal, AccessFlags.HostWrite, AccessFlags.TransferWrite);

            var subresource = new ImageSubresourceLayers(ImageAspectFlags.Color, 0, 0, 1);
            var imageCopy   = new BufferImageCopy(0, 0, 0, subresource, new Offset3D(0, 0, 0), new Extent3D(imageData.Width, imageData.Height, 1));

            cmdBuffer.CopyBufferToImage(imageBuffer, imageData.Image, ImageLayout.TransferDstOptimal, new BufferImageCopy[] { imageCopy });

            PipelineBarrierSetLayout(cmdBuffer, imageData.Image, ImageLayout.TransferDstOptimal, ImageLayout.ColorAttachmentOptimal, AccessFlags.TransferWrite, AccessFlags.ColorAttachmentWrite);

            cmdBuffer.End();

            var submitInfo = new SubmitInfo(null, null, new[] { cmdBuffer }, null);

            queue.Submit(new[] { submitInfo });
            submitInfo.Dispose();
            queue.WaitIdle();

            device.FreeCommandBuffers(cmdPool, new[] { cmdBuffer });
        }
Ejemplo n.º 3
0
 public unsafe void Begin(ref CommandBufferBeginInfo beginInfo)
 {
     fixed (CommandBufferBeginInfo* __beginInfo__ = &beginInfo)
     {
         vkBeginCommandBuffer(this, __beginInfo__).CheckError();
     }
 }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 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.
        }
Ejemplo n.º 6
0
        public void Begin(CommandBufferBeginInfo pBeginInfo)
        {
            Result result;

            unsafe {
                result = Interop.NativeMethods.vkBeginCommandBuffer(this.m, pBeginInfo != null ? pBeginInfo.m : (Interop.CommandBufferBeginInfo *) default(IntPtr));
                if (result != Result.Success)
                {
                    throw new ResultException(result);
                }
            }
        }
Ejemplo n.º 7
0
            public void BeginRecording()
            {
                if (!_hasStarted)
                {
                    _hasStarted = true;

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

                    _device.Api.BeginCommandBuffer(InternalHandle, beginInfo);
                }
            }
        protected static void BeginCommandBuffer(CommandBuffer buffer, CommandBufferUsageFlags flags, CommandBufferInheritanceInfo *inheritInfo)
        {
            var info = new CommandBufferBeginInfo
            {
                SType            = StructureType.CommandBufferBeginInfo,
                Flags            = flags,
                PInheritanceInfo = inheritInfo
            };

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

            if (res != Result.Success)
            {
                throw new VMASharp.VulkanResultException("Failed to begin Command Buffer recording!", res);
            }
        }
Ejemplo n.º 9
0
        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();
        }
Ejemplo n.º 10
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();
            }
        }
Ejemplo n.º 11
0
        protected override void InitCommandBuffers()
        {
            for (int i = 0; i < bufferSize; i++)
            {
                var beginInfo = new CommandBufferBeginInfo
                {
                    Flags = CommandBufferUsageFlags.SimultaneousUse
                };
                commandBuffers[i].Begin(beginInfo);

                var clearColor = new ClearValue
                {
                    Color = new ClearColorValue(new float[] { 25 / 255f, 0.0f, 10 / 255f, 1.0f })
                };
                var renderPassInfo = new RenderPassBeginInfo
                {
                    RenderPass  = renderPass,
                    Framebuffer = framebuffers[i],
                    RenderArea  = new Rect2D
                    {
                        Offset = new Offset2D
                        {
                            X = 0,
                            Y = 0
                        },
                        Extent = extent
                    },
                    ClearValueCount = 1,
                    ClearValues     = new ClearValue[] { clearColor }
                };
                commandBuffers[i].CmdBeginRenderPass(renderPassInfo, SubpassContents.Inline);
                commandBuffers[i].CmdBindPipeline(PipelineBindPoint.Graphics, graphicsPipeline);

                commandBuffers[i].CmdBindVertexBuffer(0, vertexBuffer, 0);
                commandBuffers[i].CmdBindIndexBuffer(indexBuffer, 0, IndexType.Uint32);

                commandBuffers[i].CmdBindDescriptorSet(PipelineBindPoint.Graphics, pipelineLayout, 0, descriptorSets[i], null);

                commandBuffers[i].CmdDrawIndexed((uint)mesh.indices.Length, 1, 0, 0, 0);

                commandBuffers[i].CmdEndRenderPass();
                commandBuffers[i].End();
            }
        }
Ejemplo n.º 12
0
        public void BeginBuffer(CommandBuffer cb,
                                int frameBufIndex, ClearValue cv)
        {
            CommandBufferBeginInfo cbbi = new CommandBufferBeginInfo();

            cbbi.Flags = CommandBufferUsages.SimultaneousUse;

            cb.Begin(cbbi);

            RenderPassBeginInfo rpbi = new RenderPassBeginInfo(
                mChainBuffers[frameBufIndex],
                new Rect2D(Offset2D.Zero, mDevices.GetChainExtent()), cv);

            //rpbi.ClearValues	=cv;

            cb.CmdBeginRenderPass(rpbi);

            cb.CmdBindPipeline(PipelineBindPoint.Graphics, mPipe);
        }
Ejemplo n.º 13
0
        void CreateCommandBuffer(CommandBuffer cmdBuffer, VertexData vertexData, RenderPass renderPass, PipelineLayout pipelineLayout, Pipeline pipeline, DescriptorSet descriptorSet, ImageData swapchainImageData, Framebuffer framebuffer)
        {
            var beginInfo = new CommandBufferBeginInfo();

            cmdBuffer.Begin(beginInfo);
            beginInfo.Dispose();

            PipelineBarrierSetLayout(cmdBuffer, swapchainImageData.Image, ImageLayout.PresentSrcKHR, ImageLayout.ColorAttachmentOptimal, AccessFlags.MemoryRead, AccessFlags.ColorAttachmentWrite);

            var clearRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1);

            cmdBuffer.ClearColorImage(swapchainImageData.Image, ImageLayout.TransferDstOptimal, new ClearColorValue(), new[] { clearRange });

            RenderTexturedQuad(cmdBuffer, vertexData, swapchainImageData, pipelineLayout, descriptorSet, renderPass, pipeline, framebuffer, swapchainImageData.Width, swapchainImageData.Height);

            PipelineBarrierSetLayout(cmdBuffer, swapchainImageData.Image, ImageLayout.ColorAttachmentOptimal, ImageLayout.PresentSrcKHR, AccessFlags.ColorAttachmentWrite, AccessFlags.MemoryRead);

            cmdBuffer.End();
        }
Ejemplo n.º 14
0
        List <ImageData> InitializeSwapchainImages(Queue queue, CommandPool cmdPool, Image[] images, Format imageFormat)
        {
            var cmdBuffers = AllocateCommandBuffers(cmdPool, 1);
            var cmdBuffer  = cmdBuffers.First();

            var inheritanceInfo = new CommandBufferInheritanceInfo();
            var beginInfo       = new CommandBufferBeginInfo {
                InheritanceInfo = inheritanceInfo
            };

            cmdBuffer.Begin(beginInfo);

            foreach (var img in images)
            {
                PipelineBarrierSetLayout(cmdBuffer, img, ImageLayout.Undefined, ImageLayout.PresentSrcKHR, AccessFlags.None, AccessFlags.None);
            }

            cmdBuffer.End();

            var submitInfo = new SubmitInfo(null, null, new[] { cmdBuffer }, null);

            queue.Submit(new[] { submitInfo });
            queue.WaitIdle();

            device.FreeCommandBuffers(cmdPool, new[] { cmdBuffer });

            var imageDatas = new List <ImageData>();

            foreach (var img in images)
            {
                var imgData = new ImageData();
                imgData.Image  = img;
                imgData.Width  = 800;
                imgData.Height = 600;
                imgData.View   = CreateImageView(img, imageFormat);
                imageDatas.Add(imgData);
            }

            return(imageDatas);
        }
Ejemplo n.º 15
0
        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);
        }
Ejemplo n.º 16
0
        private unsafe void InitializeImage(DataBox[] dataBoxes)
        {
            var commandBuffer = GraphicsDevice.NativeCopyCommandBuffer;
            var beginInfo     = new CommandBufferBeginInfo {
                StructureType = StructureType.CommandBufferBeginInfo
            };

            commandBuffer.Begin(ref beginInfo);

            if (dataBoxes != null && dataBoxes.Length > 0)
            {
                int totalSize = dataBoxes.Length * 4;
                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.TopOfPipe, 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);

                    SubresourceLayout layout;
                    GraphicsDevice.NativeDevice.GetImageSubresourceLayout(NativeImage, new ImageSubresource(NativeImageAspect, (uint)arraySlice, (uint)mipSlice), out layout);

                    var alignment = ((uploadOffset + 3) & ~3) - 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, arraySlice),
                        ImageExtent       = new Extent3D((uint)mipMapDescription.Width, (uint)mipMapDescription.Height, 1)
                    };

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

            GraphicsDevice.NativeCommandQueue.Submit(1, &submitInfo, Fence.Null);
            GraphicsDevice.NativeCommandQueue.WaitIdle();
            commandBuffer.Reset(CommandBufferResetFlags.None);
        }
        private unsafe void CreateBackBuffers()
        {
            // Create the texture object
            var backBufferDescription = new TextureDescription
            {
                ArraySize = 1,
                Dimension = TextureDimension.Texture2D,
                Height = Description.BackBufferHeight,
                Width = Description.BackBufferWidth,
                Depth = 1,
                Flags = TextureFlags.RenderTarget,
                Format = Description.BackBufferFormat,
                MipLevels = 1,
                MultiSampleLevel = MSAALevel.None,
                Usage = GraphicsResourceUsage.Default
            };
            backbuffer.InitializeWithoutResources(backBufferDescription);

            var createInfo = new ImageViewCreateInfo
            {
                StructureType = StructureType.ImageViewCreateInfo,
                SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1),
                Format = backbuffer.NativeFormat,
            };

            // We initialize swapchain images to PresentSource, since we swap them out while in this layout.
            backbuffer.NativeAccessMask = AccessFlags.MemoryRead;
            backbuffer.NativeLayout = ImageLayout.PresentSource;

            var imageMemoryBarrier = new ImageMemoryBarrier
            {
                StructureType = StructureType.ImageMemoryBarrier,
                SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1),
                OldLayout = ImageLayout.Undefined,
                NewLayout = ImageLayout.PresentSource,
                SourceAccessMask = AccessFlags.None,
                DestinationAccessMask = AccessFlags.MemoryRead
            };

            var commandBuffer = GraphicsDevice.NativeCopyCommandBuffer;
            var beginInfo = new CommandBufferBeginInfo { StructureType = StructureType.CommandBufferBeginInfo };
            commandBuffer.Begin(ref beginInfo);

            var buffers = GraphicsDevice.NativeDevice.GetSwapchainImages(swapChain);
            swapchainImages = new SwapChainImageInfo[buffers.Length];

            for (int i = 0; i < buffers.Length; i++)
            {
                // Create image views
                swapchainImages[i].NativeImage = createInfo.Image = buffers[i];
                swapchainImages[i].NativeColorAttachmentView = GraphicsDevice.NativeDevice.CreateImageView(ref createInfo);

                // Transition to default layout
                imageMemoryBarrier.Image = buffers[i];
                commandBuffer.PipelineBarrier(PipelineStageFlags.AllCommands, 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),
            };
            GraphicsDevice.NativeCommandQueue.Submit(1, &submitInfo, Fence.Null);
            GraphicsDevice.NativeCommandQueue.WaitIdle();
            commandBuffer.Reset(CommandBufferResetFlags.None);

            // Get next image
            currentBufferIndex = GraphicsDevice.NativeDevice.AcquireNextImage(swapChain, ulong.MaxValue, GraphicsDevice.GetNextPresentSemaphore(), Fence.Null);
            
            // Apply the first swap chain image to the texture
            backbuffer.SetNativeHandles(swapchainImages[currentBufferIndex].NativeImage, swapchainImages[currentBufferIndex].NativeColorAttachmentView);
        }
Ejemplo n.º 18
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();
            }
        }
        private unsafe void CreateBackBuffers()
        {
            backbuffer.OnDestroyed();

            // Create the texture object
            var backBufferDescription = new TextureDescription
            {
                ArraySize        = 1,
                Dimension        = TextureDimension.Texture2D,
                Height           = Description.BackBufferHeight,
                Width            = Description.BackBufferWidth,
                Depth            = 1,
                Flags            = TextureFlags.RenderTarget,
                Format           = Description.BackBufferFormat,
                MipLevels        = 1,
                MultisampleCount = MultisampleCount.None,
                Usage            = GraphicsResourceUsage.Default
            };

            backbuffer.InitializeWithoutResources(backBufferDescription);

            var createInfo = new ImageViewCreateInfo
            {
                StructureType    = StructureType.ImageViewCreateInfo,
                SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1),
                Format           = backbuffer.NativeFormat,
                ViewType         = ImageViewType.Image2D
            };

            // We initialize swapchain images to PresentSource, since we swap them out while in this layout.
            backbuffer.NativeAccessMask = AccessFlags.MemoryRead;
            backbuffer.NativeLayout     = ImageLayout.PresentSource;

            var imageMemoryBarrier = new ImageMemoryBarrier
            {
                StructureType         = StructureType.ImageMemoryBarrier,
                SubresourceRange      = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1),
                OldLayout             = ImageLayout.Undefined,
                NewLayout             = ImageLayout.PresentSource,
                SourceAccessMask      = AccessFlags.None,
                DestinationAccessMask = AccessFlags.MemoryRead
            };

            var commandBuffer = GraphicsDevice.NativeCopyCommandBuffer;
            var beginInfo     = new CommandBufferBeginInfo {
                StructureType = StructureType.CommandBufferBeginInfo
            };

            commandBuffer.Begin(ref beginInfo);

            var buffers = GraphicsDevice.NativeDevice.GetSwapchainImages(swapChain);

            swapchainImages = new SwapChainImageInfo[buffers.Length];

            for (int i = 0; i < buffers.Length; i++)
            {
                // Create image views
                swapchainImages[i].NativeImage = createInfo.Image = buffers[i];
                swapchainImages[i].NativeColorAttachmentView = GraphicsDevice.NativeDevice.CreateImageView(ref createInfo);

                // Transition to default layout
                imageMemoryBarrier.Image = buffers[i];
                commandBuffer.PipelineBarrier(PipelineStageFlags.AllCommands, 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),
            };

            GraphicsDevice.NativeCommandQueue.Submit(1, &submitInfo, Fence.Null);
            GraphicsDevice.NativeCommandQueue.WaitIdle();
            commandBuffer.Reset(CommandBufferResetFlags.None);

            // need to make a fence, but can immediately reset it, as it acts as a dummy
            var fenceCreateInfo = new FenceCreateInfo {
                StructureType = StructureType.FenceCreateInfo
            };

            presentFence = GraphicsDevice.NativeDevice.CreateFence(ref fenceCreateInfo);

            currentBufferIndex = GraphicsDevice.NativeDevice.AcquireNextImage(swapChain, ulong.MaxValue, SharpVulkan.Semaphore.Null, presentFence);

            fixed(Fence *fences = &presentFence)
            {
                GraphicsDevice.NativeDevice.ResetFences(1, fences);
            }

            // Apply the first swap chain image to the texture
            backbuffer.SetNativeHandles(swapchainImages[currentBufferIndex].NativeImage, swapchainImages[currentBufferIndex].NativeColorAttachmentView);
        }
Ejemplo n.º 20
0
        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);
            }
        }
Ejemplo n.º 21
0
        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);
        }
Ejemplo n.º 22
0
        protected unsafe virtual void Draw()
        {
            var semaphoreCreateInfo = new SemaphoreCreateInfo { StructureType = StructureType.SemaphoreCreateInfo };
            var presentCompleteSemaphore = device.CreateSemaphore(ref semaphoreCreateInfo);

            try
            {
                // Get the index of the next available swapchain image
                currentBackBufferIndex = device.AcquireNextImage(this.swapchain, ulong.MaxValue, presentCompleteSemaphore, Fence.Null);
            }
            catch (SharpVulkanException e) when (e.Result == Result.ErrorOutOfDate)
            {
                // TODO: Handle resize and retry draw
                throw new NotImplementedException();
            }

            // Record drawing command buffer
            var beginInfo = new CommandBufferBeginInfo { StructureType = StructureType.CommandBufferBeginInfo };
            commandBuffer.Begin(ref beginInfo);
            DrawInternal();
            commandBuffer.End();

            // Submit
            var drawCommandBuffer = commandBuffer;
            var pipelineStageFlags = PipelineStageFlags.BottomOfPipe;
            var submitInfo = new SubmitInfo
            {
                StructureType = StructureType.SubmitInfo,
                WaitSemaphoreCount = 1,
                WaitSemaphores = new IntPtr(&presentCompleteSemaphore),
                WaitDstStageMask = new IntPtr(&pipelineStageFlags),
                CommandBufferCount = 1,
                CommandBuffers = new IntPtr(&drawCommandBuffer),
            };
            queue.Submit(1, &submitInfo, Fence.Null);

            // Present
            var swapchain = this.swapchain;
            var currentBackBufferIndexCopy = currentBackBufferIndex;
            var presentInfo = new PresentInfo
            {
                StructureType = StructureType.PresentInfo,
                SwapchainCount = 1,
                Swapchains = new IntPtr(&swapchain),
                ImageIndices = new IntPtr(&currentBackBufferIndexCopy)
            };
            queue.Present(ref presentInfo);

            // Wait
            queue.WaitIdle();

            device.ResetDescriptorPool(descriptorPool, DescriptorPoolResetFlags.None);

            // Cleanup
            device.DestroySemaphore(presentCompleteSemaphore);
        }
Ejemplo n.º 23
0
        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);
        }
Ejemplo n.º 24
0
        protected virtual unsafe void Draw()
        {
            var semaphoreCreateInfo = new SemaphoreCreateInfo {
                StructureType = StructureType.SemaphoreCreateInfo
            };
            var presentCompleteSemaphore = device.CreateSemaphore(ref semaphoreCreateInfo);

            try
            {
                // Get the index of the next available swapchain image
                currentBackBufferIndex = device.AcquireNextImage(this.swapchain, ulong.MaxValue, presentCompleteSemaphore, Fence.Null);
            }
            catch (SharpVulkanException e) when(e.Result == Result.ErrorOutOfDate)
            {
                // TODO: Handle resize and retry draw
                throw new NotImplementedException();
            }

            // Record drawing command buffer
            var beginInfo = new CommandBufferBeginInfo {
                StructureType = StructureType.CommandBufferBeginInfo
            };

            commandBuffer.Begin(ref beginInfo);
            DrawInternal();
            commandBuffer.End();

            // Submit
            var drawCommandBuffer  = commandBuffer;
            var pipelineStageFlags = PipelineStageFlags.BottomOfPipe;
            var submitInfo         = new SubmitInfo
            {
                StructureType      = StructureType.SubmitInfo,
                WaitSemaphoreCount = 1,
                WaitSemaphores     = new IntPtr(&presentCompleteSemaphore),
                WaitDstStageMask   = new IntPtr(&pipelineStageFlags),
                CommandBufferCount = 1,
                CommandBuffers     = new IntPtr(&drawCommandBuffer),
            };

            queue.Submit(1, &submitInfo, Fence.Null);

            // Present
            var swapchain = this.swapchain;
            var currentBackBufferIndexCopy = currentBackBufferIndex;
            var presentInfo = new PresentInfo
            {
                StructureType  = StructureType.PresentInfo,
                SwapchainCount = 1,
                Swapchains     = new IntPtr(&swapchain),
                ImageIndices   = new IntPtr(&currentBackBufferIndexCopy)
            };

            queue.Present(ref presentInfo);

            // Wait
            queue.WaitIdle();

            device.ResetDescriptorPool(descriptorPool, DescriptorPoolResetFlags.None);

            // Cleanup
            device.DestroySemaphore(presentCompleteSemaphore);
        }
Ejemplo n.º 25
0
        private unsafe void InitializeImage(DataBox[] dataBoxes)
        {
            var commandBuffer = GraphicsDevice.NativeCopyCommandBuffer;
            var beginInfo = new CommandBufferBeginInfo { StructureType = StructureType.CommandBufferBeginInfo };
            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.TopOfPipe, 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);

                    SubresourceLayout layout;
                    GraphicsDevice.NativeDevice.GetImageSubresourceLayout(NativeImage, new ImageSubresource(NativeImageAspect, (uint)arraySlice, (uint)mipSlice), out layout);

                    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, arraySlice),
                        ImageExtent = new Extent3D((uint)mipMapDescription.Width, (uint)mipMapDescription.Height, 1)
                    };

                    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();
                commandBuffer.Reset(CommandBufferResetFlags.None);
            }
        }
Ejemplo n.º 26
0
        void RecordCommandBuffers()
        {
            var graphics_commandd_buffer_begin_info = new CommandBufferBeginInfo
            {
                sType            = StructureType.CommandBufferBeginInfo,             // VkStructureType                        sType
                pNext            = IntPtr.Zero,                                      // const void                            *pNext
                flags            = CommandBufferUsageFlagBits.SimultaneousUseBit,    // VkCommandBufferUsageFlagBits              flags
                pInheritanceInfo = (CommandBufferInheritanceInfo *)0                 // const VkCommandBufferInheritanceInfo  *pInheritanceInfo
            };

            var image_subresource_range = new ImageSubresourceRange
            {
                aspectMask     = ImageAspectFlagBits.ColorBit,       // VkImageAspectFlagBits             aspectMask
                baseMipLevel   = 0,                                  // uint32_t                       baseMipLevel
                layerCount     = 1,                                  // uint32_t                       levelCount
                baseArrayLayer = 0,                                  // uint32_t                       baseArrayLayer
                levelCount     = 1                                   // uint32_t                       layerCount
            };

            var clear_value = new ClearValue
            {
                color = new ClearColorValue(1.0f, 0.8f, 0.4f, 0.0f),                    // VkClearColorValue              color
            };

            ImageParameters[] swap_chain_images = GetSwapChain.Images;

            for (int i = 0; i < Vulkan.GraphicsCommandBuffers.Length; ++i)
            {
                vk.BeginCommandBuffer(Vulkan.GraphicsCommandBuffers[i], ref graphics_commandd_buffer_begin_info).CheckError();

                if (GetPresentQueue.Handle != GetGraphicsQueue.Handle)
                {
                    var barrier_from_present_to_draw = new ImageMemoryBarrier
                    {
                        sType                       = StructureType.ImageMemoryBarrier,                     // VkStructureType                sType
                        pNext                       = IntPtr.Zero,                                          // const void                    *pNext
                        sourceAccessMask            = AccessFlagBits.MemoryReadBit,                         // VkAccessFlagBits                  srcAccessMask
                        destinationAccessMask       = AccessFlagBits.ColorAttachmentWriteBit,               // VkAccessFlagBits                  dstAccessMask
                        oldLayout                   = ImageLayout.Undefined,                                // VkImageLayout                  oldLayout
                        newLayout                   = ImageLayout.PresentSourceKhr,                         // VkImageLayout                  newLayout
                        sourceQueueFamilyIndex      = GetPresentQueue.FamilyIndex,                          // uint32_t                       srcQueueFamilyIndex
                        destinationQueueFamilyIndex = GetGraphicsQueue.FamilyIndex,                         // uint32_t                       dstQueueFamilyIndex
                        image                       = swap_chain_images[i].Handle,                          // VkImage                        image
                        subresourceRange            = image_subresource_range                               // VkImageSubresourceRange        subresourceRange
                    };
                    vk.CmdPipelineBarrier(
                        Vulkan.GraphicsCommandBuffers[i],
                        PipelineStageFlagBits.ColorAttachmentOutputBit,
                        PipelineStageFlagBits.ColorAttachmentOutputBit,
                        (DependencyFlagBits)0,
                        0, (MemoryBarrier *)0,
                        0, (BufferMemoryBarrier *)0,
                        1, &barrier_from_present_to_draw);
                }

                var render_pass_begin_info = new RenderPassBeginInfo
                {
                    sType       = StructureType.RenderPassBeginInfo,               // VkStructureType                sType
                    pNext       = IntPtr.Zero,                                     // const void                    *pNext
                    renderPass  = Vulkan.RenderPass,                               // VkRenderPass                   renderPass
                    framebuffer = Vulkan.Framebuffers[i],                          // VkFramebuffer                  framebuffer
                    renderArea  = new Rect2D
                    {                                                              // VkRect2D                       renderArea
                        offset = new Offset2D
                        {                                                          // VkOffset2D                     offset
                            x = 0,                                                 // int32_t                        x
                            y = 0                                                  // int32_t                        y
                        },
                        extent = new Extent2D
                        {                                                               // VkExtent2D                     extent
                            width  = 300,                                               // int32_t                        width
                            height = 300,                                               // int32_t                        height
                        }
                    },
                    clearValueCount = 1,                                           // uint32_t                       clearValueCount
                    pClearValues    = &clear_value                                 // const VkClearValue            *pClearValues
                };

                vk.CmdBeginRenderPass(Vulkan.GraphicsCommandBuffers[i], ref render_pass_begin_info, SubpassContents.Inline);

                vk.CmdBindPipeline(Vulkan.GraphicsCommandBuffers[i], PipelineBindPoint.Graphics, Vulkan.GraphicsPipeline);

                vk.CmdDraw(Vulkan.GraphicsCommandBuffers[i], 3, 1, 0, 0);

                vk.CmdEndRenderPass(Vulkan.GraphicsCommandBuffers[i]);

                if (GetGraphicsQueue.Handle != GetPresentQueue.Handle)
                {
                    var barrier_from_draw_to_present = new ImageMemoryBarrier
                    {
                        sType                       = StructureType.ImageMemoryBarrier,                    // VkStructureType              sType
                        pNext                       = IntPtr.Zero,                                         // const void                  *pNext
                        sourceAccessMask            = AccessFlagBits.ColorAttachmentWriteBit,              // VkAccessFlagBits                srcAccessMask
                        destinationAccessMask       = AccessFlagBits.MemoryReadBit,                        // VkAccessFlagBits                dstAccessMask
                        oldLayout                   = ImageLayout.PresentSourceKhr,                        // VkImageLayout                oldLayout
                        newLayout                   = ImageLayout.PresentSourceKhr,                        // VkImageLayout                newLayout
                        sourceQueueFamilyIndex      = GetGraphicsQueue.FamilyIndex,                        // uint32_t                     srcQueueFamilyIndex
                        destinationQueueFamilyIndex = GetPresentQueue.FamilyIndex,                         // uint32_t                     dstQueueFamilyIndex
                        image                       = swap_chain_images[i].Handle,                         // VkImage                      image
                        subresourceRange            = image_subresource_range                              // VkImageSubresourceRange      subresourceRange
                    };
                    vk.CmdPipelineBarrier(
                        Vulkan.GraphicsCommandBuffers[i],
                        PipelineStageFlagBits.ColorAttachmentOutputBit,
                        PipelineStageFlagBits.BottomOfPipeBit,
                        (DependencyFlagBits)0,
                        0, (MemoryBarrier *)0,
                        0, (BufferMemoryBarrier *)0,
                        1, &barrier_from_draw_to_present);
                }
                vk.EndCommandBuffer(Vulkan.GraphicsCommandBuffers[i]).CheckError();
            }
        }
Ejemplo n.º 27
0
        ImageData LoadTexture(string filename, Queue queue, CommandPool cmdPool)
        {
            //
            var bmp = new Bitmap(filename);

            var bitmapFormat = System.Drawing.Imaging.PixelFormat.Format32bppArgb;
            var rect         = new Rectangle(0, 0, bmp.Width, bmp.Height);
            var bitmapData   = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmapFormat);
            //

            uint imageWidth  = (uint)bmp.Width;
            uint imageHeight = (uint)bmp.Height;

            var imageData = new ImageData();

            imageData.Width   = imageWidth;
            imageData.Height  = imageHeight;
            imageData.Image   = CreateTextureImage(Format.B8g8r8a8Unorm, imageWidth, imageHeight);
            imageData.Memory  = BindImage(imageData.Image);
            imageData.View    = CreateImageView(imageData.Image, Format.B8g8r8a8Unorm);
            imageData.Sampler = CreateSampler();

            var memRequirements = device.GetImageMemoryRequirements(imageData.Image);
            var imageBuffer     = CreateBuffer(memRequirements.Size, BufferUsageFlags.TransferSrc | BufferUsageFlags.TransferDst);
            var memoryIndex     = FindMemoryIndex(MemoryPropertyFlags.HostVisible);
            var memAlloc        = new MemoryAllocateInfo(memRequirements.Size, memoryIndex);
            var bufferMemory    = BindBuffer(imageBuffer, memAlloc);

            CopyBitmapToBuffer(bitmapData.Scan0, (int)(imageWidth * imageHeight * 4), bufferMemory, memRequirements);

            //
            var cmdBuffers = AllocateCommandBuffers(cmdPool, 1);
            var cmdBuffer  = cmdBuffers[0];

            var beginInfo = new CommandBufferBeginInfo();

            cmdBuffer.Begin(beginInfo);

            PipelineBarrierSetLayout(cmdBuffer, imageData.Image, ImageLayout.Preinitialized, ImageLayout.TransferDstOptimal, AccessFlags.HostWrite, AccessFlags.TransferWrite);
            CopyBufferToImage(cmdBuffer, imageData, imageBuffer);
            PipelineBarrierSetLayout(cmdBuffer, imageData.Image, ImageLayout.TransferDstOptimal, ImageLayout.ShaderReadOnlyOptimal, AccessFlags.TransferWrite, AccessFlags.ShaderRead);

            // wait... why does this work?
            device.DestroyBuffer(imageBuffer);
            device.FreeMemory(bufferMemory);

            cmdBuffer.End();

            var submitInfo = new SubmitInfo(null, null, new[] { cmdBuffer }, null);

            queue.Submit(new[] { submitInfo });
            submitInfo.Dispose();
            queue.WaitIdle();

            device.FreeCommandBuffers(cmdPool, new[] { cmdBuffer });
            //

            //CopyBufferToImage(queue, cmdPool, imageData, imageBuffer);

            //
            bmp.UnlockBits(bitmapData);
            bmp.Dispose();
            //

            return(imageData);
        }
Ejemplo n.º 28
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();
            }
        }
Ejemplo n.º 29
0
 internal static unsafe extern Result vkBeginCommandBuffer(CommandBuffer commandBuffer, CommandBufferBeginInfo* beginInfo);