Example #1
0
        protected override void SetVertexBufferCore(uint index, DeviceBuffer buffer, uint offset)
        {
            VkBuffer vkBuffer = Util.AssertSubtype <DeviceBuffer, VkBuffer>(buffer);

            Vulkan.VkBuffer deviceBuffer = vkBuffer.DeviceBuffer;
            ulong           offset64     = offset;

            vkCmdBindVertexBuffers(_cb, index, 1, ref deviceBuffer, ref offset64);
        }
Example #2
0
        public override void SetVertexBuffer(uint index, VertexBuffer vb)
        {
            VkBuffer vkBuffer = Util.AssertSubtype <VertexBuffer, VkVertexBuffer>(vb);

            Vulkan.VkBuffer deviceBuffer = vkBuffer.DeviceBuffer;
            ulong           offset       = 0;

            vkCmdBindVertexBuffers(_cb, index, 1, ref deviceBuffer, ref offset);
        }
Example #3
0
        protected override void SetVertexBufferCore(uint index, Buffer buffer)
        {
            VkBuffer vkBuffer = Util.AssertSubtype <Buffer, VkBuffer>(buffer);

            Vulkan.VkBuffer deviceBuffer = vkBuffer.DeviceBuffer;
            ulong           offset       = 0;

            vkCmdBindVertexBuffers(_cb, index, 1, ref deviceBuffer, ref offset);
            _referencedResources.Add(vkBuffer);
        }
Example #4
0
        internal static void CopyTextureCore_VkCommandBuffer(
            VkCommandBuffer cb,
            Texture source,
            uint srcX, uint srcY, uint srcZ,
            uint srcMipLevel,
            uint srcBaseArrayLayer,
            Texture destination,
            uint dstX, uint dstY, uint dstZ,
            uint dstMipLevel,
            uint dstBaseArrayLayer,
            uint width, uint height, uint depth,
            uint layerCount)
        {
            VkTexture srcVkTexture = Util.AssertSubtype <Texture, VkTexture>(source);
            VkTexture dstVkTexture = Util.AssertSubtype <Texture, VkTexture>(destination);

            bool sourceIsStaging = (source.Usage & TextureUsage.Staging) == TextureUsage.Staging;
            bool destIsStaging   = (destination.Usage & TextureUsage.Staging) == TextureUsage.Staging;

            if (!sourceIsStaging && !destIsStaging)
            {
                VkImageSubresourceLayers srcSubresource = new VkImageSubresourceLayers
                {
                    aspectMask     = VkImageAspectFlags.Color,
                    layerCount     = layerCount,
                    mipLevel       = srcMipLevel,
                    baseArrayLayer = srcBaseArrayLayer
                };

                VkImageSubresourceLayers dstSubresource = new VkImageSubresourceLayers
                {
                    aspectMask     = VkImageAspectFlags.Color,
                    layerCount     = layerCount,
                    mipLevel       = dstMipLevel,
                    baseArrayLayer = dstBaseArrayLayer
                };

                VkImageCopy region = new VkImageCopy
                {
                    srcOffset = new VkOffset3D {
                        x = (int)srcX, y = (int)srcY, z = (int)srcZ
                    },
                    dstOffset = new VkOffset3D {
                        x = (int)dstX, y = (int)dstY, z = (int)dstZ
                    },
                    srcSubresource = srcSubresource,
                    dstSubresource = dstSubresource,
                    extent         = new VkExtent3D {
                        width = width, height = height, depth = depth
                    }
                };

                srcVkTexture.TransitionImageLayout(
                    cb,
                    srcMipLevel,
                    1,
                    srcBaseArrayLayer,
                    layerCount,
                    VkImageLayout.TransferSrcOptimal);

                dstVkTexture.TransitionImageLayout(
                    cb,
                    dstMipLevel,
                    1,
                    dstBaseArrayLayer,
                    layerCount,
                    VkImageLayout.TransferDstOptimal);

                vkCmdCopyImage(
                    cb,
                    srcVkTexture.OptimalDeviceImage,
                    VkImageLayout.TransferSrcOptimal,
                    dstVkTexture.OptimalDeviceImage,
                    VkImageLayout.TransferDstOptimal,
                    1,
                    ref region);
            }
            else if (sourceIsStaging && !destIsStaging)
            {
                Vulkan.VkBuffer     srcBuffer = srcVkTexture.StagingBuffer;
                VkSubresourceLayout srcLayout = srcVkTexture.GetSubresourceLayout(
                    srcVkTexture.CalculateSubresource(srcMipLevel, srcBaseArrayLayer));
                VkImage dstImage = dstVkTexture.OptimalDeviceImage;
                dstVkTexture.TransitionImageLayout(
                    cb,
                    dstMipLevel,
                    1,
                    dstBaseArrayLayer,
                    layerCount,
                    VkImageLayout.TransferDstOptimal);

                VkImageSubresourceLayers dstSubresource = new VkImageSubresourceLayers
                {
                    aspectMask     = VkImageAspectFlags.Color,
                    layerCount     = layerCount,
                    mipLevel       = dstMipLevel,
                    baseArrayLayer = dstBaseArrayLayer
                };

                Util.GetMipDimensions(srcVkTexture, srcMipLevel, out uint mipWidth, out uint mipHeight, out uint mipDepth);
                uint blockSize         = FormatHelpers.IsCompressedFormat(srcVkTexture.Format) ? 4u : 1u;
                uint bufferRowLength   = Math.Max(mipWidth, blockSize);
                uint bufferImageHeight = Math.Max(mipHeight, blockSize);
                uint compressedX       = srcX / blockSize;
                uint compressedY       = srcY / blockSize;
                uint blockSizeInBytes  = blockSize == 1
                    ? FormatHelpers.GetSizeInBytes(srcVkTexture.Format)
                    : FormatHelpers.GetBlockSizeInBytes(srcVkTexture.Format);
                uint rowPitch   = FormatHelpers.GetRowPitch(bufferRowLength, srcVkTexture.Format);
                uint depthPitch = FormatHelpers.GetDepthPitch(rowPitch, bufferImageHeight, srcVkTexture.Format);

                VkBufferImageCopy regions = new VkBufferImageCopy
                {
                    bufferOffset = srcLayout.offset
                                   + (srcZ * depthPitch)
                                   + (compressedY * rowPitch)
                                   + (compressedX * blockSizeInBytes),
                    bufferRowLength   = bufferRowLength,
                    bufferImageHeight = bufferImageHeight,
                    imageExtent       = new VkExtent3D {
                        width = width, height = height, depth = depth
                    },
                    imageOffset = new VkOffset3D {
                        x = (int)dstX, y = (int)dstY, z = (int)dstZ
                    },
                    imageSubresource = dstSubresource
                };

                vkCmdCopyBufferToImage(cb, srcBuffer, dstImage, VkImageLayout.TransferDstOptimal, 1, ref regions);
            }
            else if (!sourceIsStaging && destIsStaging)
            {
                VkImage srcImage = srcVkTexture.OptimalDeviceImage;
                srcVkTexture.TransitionImageLayout(
                    cb,
                    srcMipLevel,
                    1,
                    srcBaseArrayLayer,
                    layerCount,
                    VkImageLayout.TransferSrcOptimal);

                Vulkan.VkBuffer     dstBuffer = dstVkTexture.StagingBuffer;
                VkSubresourceLayout dstLayout = dstVkTexture.GetSubresourceLayout(
                    dstVkTexture.CalculateSubresource(dstMipLevel, dstBaseArrayLayer));
                VkImageSubresourceLayers srcSubresource = new VkImageSubresourceLayers
                {
                    aspectMask     = VkImageAspectFlags.Color,
                    layerCount     = layerCount,
                    mipLevel       = srcMipLevel,
                    baseArrayLayer = srcBaseArrayLayer
                };

                Util.GetMipDimensions(dstVkTexture, dstMipLevel, out uint mipWidth, out uint mipHeight, out uint mipDepth);
                VkBufferImageCopy region = new VkBufferImageCopy
                {
                    bufferRowLength   = mipWidth,
                    bufferImageHeight = mipHeight,
                    bufferOffset      = dstLayout.offset + (dstX * FormatHelpers.GetSizeInBytes(dstVkTexture.Format)),
                    imageExtent       = new VkExtent3D {
                        width = width, height = height, depth = depth
                    },
                    imageOffset = new VkOffset3D {
                        x = (int)dstX, y = (int)dstY, z = (int)dstZ
                    },
                    imageSubresource = srcSubresource
                };

                vkCmdCopyImageToBuffer(cb, srcImage, VkImageLayout.TransferSrcOptimal, dstBuffer, 1, ref region);
            }
            else
            {
                Debug.Assert(sourceIsStaging && destIsStaging);
                Vulkan.VkBuffer     srcBuffer = srcVkTexture.StagingBuffer;
                VkSubresourceLayout srcLayout = srcVkTexture.GetSubresourceLayout(
                    srcVkTexture.CalculateSubresource(srcMipLevel, srcBaseArrayLayer));
                Vulkan.VkBuffer     dstBuffer = dstVkTexture.StagingBuffer;
                VkSubresourceLayout dstLayout = dstVkTexture.GetSubresourceLayout(
                    dstVkTexture.CalculateSubresource(dstMipLevel, dstBaseArrayLayer));

                uint zLimit = Math.Max(depth, layerCount);
                if (!FormatHelpers.IsCompressedFormat(source.Format))
                {
                    uint pixelSize = FormatHelpers.GetSizeInBytes(srcVkTexture.Format);
                    for (uint zz = 0; zz < zLimit; zz++)
                    {
                        for (uint yy = 0; yy < height; yy++)
                        {
                            VkBufferCopy region = new VkBufferCopy
                            {
                                srcOffset = srcLayout.offset
                                            + srcLayout.depthPitch * (zz + srcZ)
                                            + srcLayout.rowPitch * (yy + srcY)
                                            + pixelSize * srcX,
                                dstOffset = dstLayout.offset
                                            + dstLayout.depthPitch * (zz + dstZ)
                                            + dstLayout.rowPitch * (yy + dstY)
                                            + pixelSize * dstX,
                                size = width * pixelSize,
                            };

                            vkCmdCopyBuffer(cb, srcBuffer, dstBuffer, 1, ref region);
                        }
                    }
                }
                else // IsCompressedFormat
                {
                    uint denseRowSize     = FormatHelpers.GetRowPitch(width, source.Format);
                    uint numRows          = FormatHelpers.GetNumRows(height, source.Format);
                    uint compressedSrcX   = srcX / 4;
                    uint compressedSrcY   = srcY / 4;
                    uint compressedDstX   = dstX / 4;
                    uint compressedDstY   = dstY / 4;
                    uint blockSizeInBytes = FormatHelpers.GetBlockSizeInBytes(source.Format);

                    for (uint zz = 0; zz < zLimit; zz++)
                    {
                        for (uint row = 0; row < numRows; row++)
                        {
                            VkBufferCopy region = new VkBufferCopy
                            {
                                srcOffset = srcLayout.offset
                                            + srcLayout.depthPitch * (zz + srcZ)
                                            + srcLayout.rowPitch * (row + compressedSrcY)
                                            + blockSizeInBytes * compressedSrcX,
                                dstOffset = dstLayout.offset
                                            + dstLayout.depthPitch * (zz + dstZ)
                                            + dstLayout.rowPitch * (row + compressedDstY)
                                            + blockSizeInBytes * compressedDstX,
                                size = denseRowSize,
                            };

                            vkCmdCopyBuffer(cb, srcBuffer, dstBuffer, 1, ref region);
                        }
                    }
                }
            }
        }
Example #5
0
        public VkMemoryBlock Allocate(
            VkPhysicalDeviceMemoryProperties memProperties,
            uint memoryTypeBits,
            VkMemoryPropertyFlags flags,
            bool persistentMapped,
            ulong size,
            ulong alignment,
            bool dedicated,
            VkImage dedicatedImage,
            Vulkan.VkBuffer dedicatedBuffer)
        {
            // Round up to the nearest multiple of bufferImageGranularity.
            size = ((size / _bufferImageGranularity) + 1) * _bufferImageGranularity;
            _totalAllocatedBytes += size;

            lock (_lock)
            {
                if (!TryFindMemoryType(memProperties, memoryTypeBits, flags, out var memoryTypeIndex))
                {
                    throw new VeldridException("No suitable memory type.");
                }

                ulong minDedicatedAllocationSize = persistentMapped
                    ? MinDedicatedAllocationSizeDynamic
                    : MinDedicatedAllocationSizeNonDynamic;

                if (dedicated || size >= minDedicatedAllocationSize)
                {
                    VkMemoryAllocateInfo allocateInfo = VkMemoryAllocateInfo.New();
                    allocateInfo.allocationSize  = size;
                    allocateInfo.memoryTypeIndex = memoryTypeIndex;

                    VkMemoryDedicatedAllocateInfoKHR dedicatedAI;
                    if (dedicated)
                    {
                        dedicatedAI        = VkMemoryDedicatedAllocateInfoKHR.New();
                        dedicatedAI.buffer = dedicatedBuffer;
                        dedicatedAI.image  = dedicatedImage;
                        allocateInfo.pNext = &dedicatedAI;
                    }

                    VkResult allocationResult = vkAllocateMemory(_device, ref allocateInfo, null, out VkDeviceMemory memory);
                    if (allocationResult != VkResult.Success)
                    {
                        throw new VeldridException("Unable to allocate sufficient Vulkan memory.");
                    }

                    void *mappedPtr = null;
                    if (persistentMapped)
                    {
                        VkResult mapResult = vkMapMemory(_device, memory, 0, size, 0, &mappedPtr);
                        if (mapResult != VkResult.Success)
                        {
                            throw new VeldridException("Unable to map newly-allocated Vulkan memory.");
                        }
                    }

                    return(new VkMemoryBlock(memory, 0, size, memoryTypeBits, mappedPtr, true));
                }
                else
                {
                    ChunkAllocatorSet allocator = GetAllocator(memoryTypeIndex, persistentMapped);
                    bool result = allocator.Allocate(size, alignment, out VkMemoryBlock ret);
                    if (!result)
                    {
                        throw new VeldridException("Unable to allocate sufficient Vulkan memory.");
                    }

                    return(ret);
                }
            }
        }
Example #6
0
 /// <summary>
 /// VkDescriptorBufferInfo - Structure specifying descriptor buffer info
 /// </summary>
 /// <param name="buffer">buffer is the buffer resource</param>
 /// <param name="offset">offset is the offset in bytes from the start of buffer.
 /// Access to buffer memory via this descriptor uses addressing that is
 /// relative to this starting offset</param>
 /// <param name="range">range is the size in bytes that is used for this descriptor
 /// update, or VK_WHOLE_SIZE to use the range from offset to the
 /// end of the buffer</param>
 public VkDescriptorBufferInfo(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize range)
 {
     this.buffer = buffer; this.offset = offset; this.range = range;
 }