예제 #1
0
        public unsafe void DestroyNow()
        {
            GraphicsDevice.RegisterBufferMemoryUsage(-SizeInBytes);

            if (NativeBufferView != VkBufferView.Null)
            {
                vkDestroyBufferView(GraphicsDevice.NativeDevice, NativeBufferView, null);
                NativeBufferView = VkBufferView.Null;
            }

            if (NativeBuffer != VkBuffer.Null)
            {
                vkDestroyBuffer(GraphicsDevice.NativeDevice, NativeBuffer, null);
                NativeBuffer = VkBuffer.Null;
            }

            if (NativeMemory != VkDeviceMemory.Null)
            {
                if (NativeMemoryOffset.HasValue)
                {
                    VulkanMemoryPool.Free(this, NativeMemoryOffset.Value);
                }
                else
                {
                    vkFreeMemory(GraphicsDevice.NativeDevice, NativeMemory, null);
                }
                NativeMemory = VkDeviceMemory.Null;
            }

            base.OnDestroyed();
        }
예제 #2
0
        /// <inheritdoc/>
        protected internal override void OnDestroyed()
        {
            Ready = false;

            GraphicsDevice.RegisterBufferMemoryUsage(-SizeInBytes);

            if (NativeBufferView != VkBufferView.Null)
            {
                GraphicsDevice.Collect(NativeBufferView);
                NativeBufferView = VkBufferView.Null;
            }

            if (NativeBuffer != VkBuffer.Null)
            {
                GraphicsDevice.Collect(NativeBuffer);
                NativeBuffer = VkBuffer.Null;
            }

            if (NativeMemory != VkDeviceMemory.Null)
            {
                if (NativeMemoryOffset.HasValue)
                {
                    VulkanMemoryPool.Free(this, NativeMemoryOffset.Value);
                }
                else
                {
                    GraphicsDevice.Collect(NativeMemory);
                }
                NativeMemory = VkDeviceMemory.Null;
            }

            base.OnDestroyed();
        }
예제 #3
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)
        {
            // capture vertex information for possible later easy batching or physics mesh generation
            if (dataPointer != IntPtr.Zero &&
                (ViewFlags == BufferFlags.VertexBuffer && (CaptureAllModelBuffers || bufferDescription.SizeInBytes <= CaptureVertexBuffersOfSize) ||
                 ViewFlags == BufferFlags.IndexBuffer && (CaptureAllModelBuffers || bufferDescription.SizeInBytes <= CaptureIndexBuffersOfSize)))
            {
                VertIndexData = new byte[Description.SizeInBytes];
                fixed(byte *vid = &VertIndexData[0])
                {
                    Utilities.CopyMemory((IntPtr)vid, dataPointer, VertIndexData.Length);
                }
            }
            else
            {
                VertIndexData = null;
            }

            var createInfo = new VkBufferCreateInfo
            {
                sType = VkStructureType.BufferCreateInfo,
                size  = (ulong)bufferDescription.SizeInBytes,
                flags = VkBufferCreateFlags.None,
            };

            createInfo.usage |= VkBufferUsageFlags.TransferSrc;
            createInfo.usage |= VkBufferUsageFlags.TransferDst;

            if (Usage == GraphicsResourceUsage.Staging)
            {
                NativeAccessMask         = VkAccessFlags.HostRead | VkAccessFlags.HostWrite;
                NativePipelineStageMask |= VkPipelineStageFlags.Host;
            }
            else
            {
                if ((ViewFlags & BufferFlags.VertexBuffer) != 0)
                {
                    createInfo.usage        |= VkBufferUsageFlags.VertexBuffer;
                    NativeAccessMask        |= VkAccessFlags.VertexAttributeRead;
                    NativePipelineStageMask |= VkPipelineStageFlags.VertexInput;
                }

                if ((ViewFlags & BufferFlags.IndexBuffer) != 0)
                {
                    createInfo.usage        |= VkBufferUsageFlags.IndexBuffer;
                    NativeAccessMask        |= VkAccessFlags.IndexRead;
                    NativePipelineStageMask |= VkPipelineStageFlags.VertexInput;
                }

                if ((ViewFlags & BufferFlags.ConstantBuffer) != 0)
                {
                    createInfo.usage        |= VkBufferUsageFlags.UniformBuffer;
                    NativeAccessMask        |= VkAccessFlags.UniformRead;
                    NativePipelineStageMask |= VkPipelineStageFlags.VertexShader | VkPipelineStageFlags.FragmentShader;
                }

                if ((ViewFlags & BufferFlags.ShaderResource) != 0)
                {
                    createInfo.usage        |= VkBufferUsageFlags.UniformTexelBuffer;
                    NativeAccessMask        |= VkAccessFlags.ShaderRead;
                    NativePipelineStageMask |= VkPipelineStageFlags.VertexShader | VkPipelineStageFlags.FragmentShader;

                    if ((ViewFlags & BufferFlags.UnorderedAccess) != 0)
                    {
                        createInfo.usage |= VkBufferUsageFlags.StorageTexelBuffer;
                        NativeAccessMask |= VkAccessFlags.ShaderWrite;
                    }
                }
            }

            // Create buffer
            vkCreateBuffer(GraphicsDevice.NativeDevice, &createInfo, null, out NativeBuffer);

            // Allocate memory
            var memoryProperties = VkMemoryPropertyFlags.DeviceLocal;

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

            vkGetBufferMemoryRequirements(GraphicsDevice.NativeDevice, NativeBuffer, out var memoryRequirements);

            if (bufferDescription.Usage == GraphicsResourceUsage.Staging || Usage == GraphicsResourceUsage.Dynamic)
            {
                AllocateMemory(memoryProperties, memoryRequirements); // special case that doesn't use a pool
            }
            else if (VulkanMemoryPool.TryAllocateMemoryForBuffer(createInfo.size, GraphicsDevice.NativeDevice, GraphicsDevice.NativePhysicalDevice, ref memoryRequirements, ref memoryProperties, out var memOffset, out var devmem))
            {
                NativeMemory       = devmem;
                NativeMemoryOffset = memOffset;
            }