Ejemplo n.º 1
0
        public static void CreateImage(
            VkDevice device,
            VkPhysicalDeviceMemoryProperties physicalDeviceMemProperties,
            VkDeviceMemoryManager memoryManager,
            uint width,
            uint height,
            uint depth,
            uint arrayLayers,
            VkFormat format,
            VkImageTiling tiling,
            VkImageUsageFlags usage,
            VkMemoryPropertyFlags properties,
            out VkImage image,
            out VkMemoryBlock memory)
        {
            VkImageCreateInfo imageCI = VkImageCreateInfo.New();

            imageCI.imageType     = VkImageType.Image2D;
            imageCI.extent.width  = width;
            imageCI.extent.height = height;
            imageCI.extent.depth  = depth;
            imageCI.mipLevels     = 1;
            imageCI.arrayLayers   = arrayLayers;
            imageCI.format        = format;
            imageCI.tiling        = tiling;
            imageCI.initialLayout = VkImageLayout.Preinitialized;
            imageCI.usage         = usage;
            imageCI.sharingMode   = VkSharingMode.Exclusive;
            imageCI.samples       = VkSampleCountFlags.Count1;

            VkResult result = vkCreateImage(device, ref imageCI, null, out image);

            CheckResult(result);

            vkGetImageMemoryRequirements(device, image, out VkMemoryRequirements memRequirements);
            VkMemoryBlock memoryToken = memoryManager.Allocate(
                physicalDeviceMemProperties,
                memRequirements.memoryTypeBits,
                properties,
                false,
                memRequirements.size,
                memRequirements.alignment);

            memory = memoryToken;
            result = vkBindImageMemory(device, image, memory.DeviceMemory, memory.Offset);
            CheckResult(result);
        }
Ejemplo n.º 2
0
        private void Setup()
        {
            disposed = false;
            VkImageCreateInfo image = VkImageCreateInfo.New();

            image.imageType = VkImageType.Image2D;
            image.format    = device.DepthFormat;
            image.extent    = new VkExtent3D()
            {
                width = swapchain.width, height = swapchain.height, depth = 1
            };
            image.mipLevels   = 1;
            image.arrayLayers = 1;
            image.samples     = VkSampleCountFlags.Count1;
            image.tiling      = VkImageTiling.Optimal;
            image.usage       = (VkImageUsageFlags.DepthStencilAttachment | VkImageUsageFlags.TransferSrc);
            image.flags       = 0;

            VkMemoryAllocateInfo mem_alloc = VkMemoryAllocateInfo.New();

            mem_alloc.allocationSize  = 0;
            mem_alloc.memoryTypeIndex = 0;

            VkImageViewCreateInfo depthStencilView = VkImageViewCreateInfo.New();

            depthStencilView.viewType                        = VkImageViewType.Image2D;
            depthStencilView.format                          = device.DepthFormat;
            depthStencilView.flags                           = 0;
            depthStencilView.subresourceRange                = new VkImageSubresourceRange();
            depthStencilView.subresourceRange.aspectMask     = (VkImageAspectFlags.Depth | VkImageAspectFlags.Stencil);
            depthStencilView.subresourceRange.baseMipLevel   = 0;
            depthStencilView.subresourceRange.levelCount     = 1;
            depthStencilView.subresourceRange.baseArrayLayer = 0;
            depthStencilView.subresourceRange.layerCount     = 1;

            Util.CheckResult(vkCreateImage(device.device, &image, null, out vkImage));
            vkGetImageMemoryRequirements(device.device, vkImage, out VkMemoryRequirements memReqs);
            mem_alloc.allocationSize  = memReqs.size;
            mem_alloc.memoryTypeIndex = device.vulkanDevice.getMemoryType(memReqs.memoryTypeBits, VkMemoryPropertyFlags.DeviceLocal);
            Util.CheckResult(vkAllocateMemory(device.device, &mem_alloc, null, out vkMem));
            Util.CheckResult(vkBindImageMemory(device.device, vkImage, vkMem, 0));

            depthStencilView.image = vkImage;
            Util.CheckResult(vkCreateImageView(device.device, ref depthStencilView, null, out vkView));
        }
Ejemplo n.º 3
0
        private void CreateDepthImage(VkPhysicalDevice physicalDevice, uint width, uint height)
        {
            VkImageCreateInfo createInfo = VkImageCreateInfo.New();

            createInfo.imageType     = VkImageType.Image2D;
            createInfo.extent.width  = width;
            createInfo.extent.height = height;
            createInfo.extent.depth  = 1;
            createInfo.mipLevels     = 1;
            createInfo.arrayLayers   = 1;
            createInfo.format        = VkFormat.D32Sfloat;
            createInfo.tiling        = VkImageTiling.Optimal;
            createInfo.initialLayout = VkImageLayout.Undefined;
            createInfo.usage         = VkImageUsageFlags.DepthStencilAttachment;
            createInfo.sharingMode   = VkSharingMode.Exclusive;
            createInfo.samples       = VkSampleCountFlags.Count1;

            VkImage depthImage;

            Assert(vkCreateImage(device, &createInfo, null, &depthImage));

            VkMemoryRequirements memoryRequirements;

            vkGetImageMemoryRequirements(device, depthImage, &memoryRequirements);

            VkPhysicalDeviceMemoryProperties memoryProperties = new VkPhysicalDeviceMemoryProperties();

            vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties);

            VkMemoryAllocateInfo allocateInfo = VkMemoryAllocateInfo.New();

            allocateInfo.allocationSize  = memoryRequirements.size;
            allocateInfo.memoryTypeIndex = FDataBuffer <byte> .SelectMemoryType(memoryProperties, memoryRequirements.memoryTypeBits,
                                                                                VkMemoryPropertyFlags.DeviceLocal);

            VkDeviceMemory depthImageMemory;

            Assert(vkAllocateMemory(device, &allocateInfo, null, &depthImageMemory));

            vkBindImageMemory(device, depthImage, depthImageMemory, 0);

            this.depthImage       = depthImage;
            this.depthImageMemory = depthImageMemory;
        }
Ejemplo n.º 4
0
        protected virtual void SetupDepthStencil()
        {
            VkImageCreateInfo image = VkImageCreateInfo.New();

            image.imageType = VkImageType._2d;
            image.format    = DepthFormat;
            image.extent    = new VkExtent3D()
            {
                width = Width, height = Height, depth = 1
            };
            image.mipLevels   = 1;
            image.arrayLayers = 1;
            image.samples     = VkSampleCountFlags._1;
            image.tiling      = VkImageTiling.Optimal;
            image.usage       = (VkImageUsageFlags.DepthStencilAttachment | VkImageUsageFlags.TransferSrc);
            image.flags       = 0;

            VkMemoryAllocateInfo mem_alloc = VkMemoryAllocateInfo.New();

            mem_alloc.allocationSize  = 0;
            mem_alloc.memoryTypeIndex = 0;

            VkImageViewCreateInfo depthStencilView = VkImageViewCreateInfo.New();

            depthStencilView.viewType                        = VkImageViewType._2d;
            depthStencilView.format                          = DepthFormat;
            depthStencilView.flags                           = 0;
            depthStencilView.subresourceRange                = new VkImageSubresourceRange();
            depthStencilView.subresourceRange.aspectMask     = (VkImageAspectFlags.Depth | VkImageAspectFlags.Stencil);
            depthStencilView.subresourceRange.baseMipLevel   = 0;
            depthStencilView.subresourceRange.levelCount     = 1;
            depthStencilView.subresourceRange.baseArrayLayer = 0;
            depthStencilView.subresourceRange.layerCount     = 1;

            Util.CheckResult(vkCreateImage(Device, &image, null, out DepthStencil.Image));
            vkGetImageMemoryRequirements(Device, DepthStencil.Image, out VkMemoryRequirements memReqs);
            mem_alloc.allocationSize  = memReqs.size;
            mem_alloc.memoryTypeIndex = VulkanDevice.GetMemoryType(memReqs.memoryTypeBits, VkMemoryPropertyFlags.DeviceLocal);
            Util.CheckResult(vkAllocateMemory(Device, &mem_alloc, null, out DepthStencil.Mem));
            Util.CheckResult(vkBindImageMemory(Device, DepthStencil.Image, DepthStencil.Mem, 0));

            depthStencilView.image = DepthStencil.Image;
            Util.CheckResult(vkCreateImageView(Device, ref depthStencilView, null, out DepthStencil.View));
        }
Ejemplo n.º 5
0
        internal VkTexture(VkGraphicsDevice gd, ref TextureDescription description)
        {
            _gd         = gd;
            _width      = description.Width;
            _height     = description.Height;
            _depth      = description.Depth;
            MipLevels   = description.MipLevels;
            ArrayLayers = description.ArrayLayers;
            bool isCubemap = ((description.Usage) & TextureUsage.Cubemap) == TextureUsage.Cubemap;

            _actualImageArrayLayers = isCubemap
                ? 6 * ArrayLayers
                : ArrayLayers;
            _format       = description.Format;
            Usage         = description.Usage;
            Type          = description.Type;
            SampleCount   = description.SampleCount;
            VkSampleCount = VkFormats.VdToVkSampleCount(SampleCount);
            VkFormat      = VkFormats.VdToVkPixelFormat(Format, (description.Usage & TextureUsage.DepthStencil) == TextureUsage.DepthStencil);

            bool isStaging = (Usage & TextureUsage.Staging) == TextureUsage.Staging;

            if (!isStaging)
            {
                VkImageCreateInfo imageCI = VkImageCreateInfo.New();
                imageCI.mipLevels     = MipLevels;
                imageCI.arrayLayers   = _actualImageArrayLayers;
                imageCI.imageType     = VkFormats.VdToVkTextureType(Type);
                imageCI.extent.width  = Width;
                imageCI.extent.height = Height;
                imageCI.extent.depth  = Depth;
                imageCI.initialLayout = VkImageLayout.Preinitialized;
                imageCI.usage         = VkFormats.VdToVkTextureUsage(Usage);
                imageCI.tiling        = isStaging ? VkImageTiling.Linear : VkImageTiling.Optimal;
                imageCI.format        = VkFormat;

                imageCI.samples = VkSampleCount;
                if (isCubemap)
                {
                    imageCI.flags = VkImageCreateFlags.CubeCompatible;
                }

                uint     subresourceCount = MipLevels * _actualImageArrayLayers * Depth;
                VkResult result           = vkCreateImage(gd.Device, ref imageCI, null, out _optimalImage);
                CheckResult(result);

                vkGetImageMemoryRequirements(gd.Device, _optimalImage, out VkMemoryRequirements memoryRequirements);

                VkMemoryBlock memoryToken = gd.MemoryManager.Allocate(
                    gd.PhysicalDeviceMemProperties,
                    memoryRequirements.memoryTypeBits,
                    VkMemoryPropertyFlags.DeviceLocal,
                    false,
                    memoryRequirements.size,
                    memoryRequirements.alignment);
                _memoryBlock = memoryToken;
                result       = vkBindImageMemory(gd.Device, _optimalImage, _memoryBlock.DeviceMemory, _memoryBlock.Offset);
                CheckResult(result);

                _imageLayouts = new VkImageLayout[subresourceCount];
                for (int i = 0; i < _imageLayouts.Length; i++)
                {
                    _imageLayouts[i] = VkImageLayout.Preinitialized;
                }
            }
            else // isStaging
            {
                uint depthPitch = FormatHelpers.GetDepthPitch(
                    FormatHelpers.GetRowPitch(Width, Format),
                    Height,
                    Format);
                uint stagingSize = depthPitch * Depth;
                for (uint level = 1; level < MipLevels; level++)
                {
                    Util.GetMipDimensions(this, level, out uint mipWidth, out uint mipHeight, out uint mipDepth);

                    depthPitch = FormatHelpers.GetDepthPitch(
                        FormatHelpers.GetRowPitch(mipWidth, Format),
                        mipHeight,
                        Format);

                    stagingSize += depthPitch * mipDepth;
                }
                stagingSize *= ArrayLayers;

                VkBufferCreateInfo bufferCI = VkBufferCreateInfo.New();
                bufferCI.usage = VkBufferUsageFlags.TransferSrc | VkBufferUsageFlags.TransferDst;
                bufferCI.size  = stagingSize;
                VkResult result = vkCreateBuffer(_gd.Device, ref bufferCI, null, out _stagingBuffer);
                CheckResult(result);
                vkGetBufferMemoryRequirements(_gd.Device, _stagingBuffer, out VkMemoryRequirements bufferMemReqs);
                _memoryBlock = _gd.MemoryManager.Allocate(
                    _gd.PhysicalDeviceMemProperties,
                    bufferMemReqs.memoryTypeBits,
                    VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent,
                    true,
                    bufferMemReqs.size,
                    bufferMemReqs.alignment);

                result = vkBindBufferMemory(_gd.Device, _stagingBuffer, _memoryBlock.DeviceMemory, _memoryBlock.Offset);
                CheckResult(result);
            }

            ClearIfRenderTarget();
        }
Ejemplo n.º 6
0
        public VkCubemapTexture(
            VkDevice device,
            VkPhysicalDevice physicalDevice,
            VkDeviceMemoryManager memoryManager,
            VkRenderContext rc,
            IntPtr pixelsFront,
            IntPtr pixelsBack,
            IntPtr pixelsLeft,
            IntPtr pixelsRight,
            IntPtr pixelsTop,
            IntPtr pixelsBottom,
            int width,
            int height,
            PixelFormat format)
        {
            _device         = device;
            _physicalDevice = physicalDevice;
            _rc             = rc;
            _memoryManager  = memoryManager;

            Width     = width;
            Height    = height;
            _format   = format;
            _vkFormat = VkFormats.VeldridToVkPixelFormat(_format);

            vkGetPhysicalDeviceImageFormatProperties(
                _physicalDevice,
                _vkFormat,
                VkImageType.Image2D,
                VkImageTiling.Linear,
                VkImageUsageFlags.Sampled,
                VkImageCreateFlags.CubeCompatible,
                out VkImageFormatProperties linearProps);

            vkGetPhysicalDeviceImageFormatProperties(
                _physicalDevice,
                _vkFormat,
                VkImageType.Image2D,
                VkImageTiling.Optimal,
                VkImageUsageFlags.Sampled,
                VkImageCreateFlags.CubeCompatible,
                out VkImageFormatProperties optimalProps);

            bool useSingleStagingBuffer = linearProps.maxArrayLayers >= 6;

            VkImageCreateInfo imageCI = VkImageCreateInfo.New();

            imageCI.imageType     = VkImageType.Image2D;
            imageCI.flags         = VkImageCreateFlags.CubeCompatible;
            imageCI.format        = _vkFormat;
            imageCI.extent.width  = (uint)width;
            imageCI.extent.height = (uint)height;
            imageCI.extent.depth  = 1;
            imageCI.mipLevels     = 1;
            imageCI.arrayLayers   = 6;
            imageCI.samples       = VkSampleCountFlags.Count1;
            imageCI.tiling        = useSingleStagingBuffer ? VkImageTiling.Linear : VkImageTiling.Optimal;
            imageCI.usage         = VkImageUsageFlags.Sampled | VkImageUsageFlags.TransferDst;
            imageCI.initialLayout = VkImageLayout.Preinitialized;

            VkResult result = vkCreateImage(_device, ref imageCI, null, out _image);

            CheckResult(result);

            vkGetImageMemoryRequirements(_device, _image, out VkMemoryRequirements memReqs);
            uint memoryType = FindMemoryType(_physicalDevice, memReqs.memoryTypeBits, VkMemoryPropertyFlags.DeviceLocal);

            _memory = memoryManager.Allocate(memoryType, memReqs.size, memReqs.alignment);
            vkBindImageMemory(_device, _image, _memory.DeviceMemory, _memory.Offset);

            if (useSingleStagingBuffer)
            {
                CopyDataSingleStagingBuffer(pixelsFront, pixelsBack, pixelsLeft, pixelsRight, pixelsTop, pixelsBottom, memReqs);
            }
            else
            {
                CopyDataMultiImage(pixelsFront, pixelsBack, pixelsLeft, pixelsRight, pixelsTop, pixelsBottom);
            }

            TransitionImageLayout(_image, (uint)MipLevels, 0, 6, VkImageLayout.TransferDstOptimal, VkImageLayout.ShaderReadOnlyOptimal);
            _imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
        }
Ejemplo n.º 7
0
        private static VkImage LoadTexture(VkDevice device, VkPhysicalDevice physicalDevice, int cmdPoolID, VkQueue queue, string[] paths, uint mipLevels)
        {
            Bitmap[]             bitmaps    = new Bitmap[paths.Length];
            FDataBuffer <byte>[] tempBuffer = new FDataBuffer <byte> [paths.Length];

            uint width = 0, height = 0;

            for (int j = 0; j < paths.Length; j++)
            {
                bitmaps[j] = new Bitmap(System.Drawing.Image.FromFile(paths[j]));

                var data = bitmaps[j].LockBits(new Rectangle(0, 0, bitmaps[j].Width, bitmaps[j].Height), System.Drawing.Imaging.ImageLockMode.ReadOnly,
                                               bitmaps[j].PixelFormat);
                width  = (uint)data.Width;
                height = (uint)data.Height;//TODO add size check


                Span <byte> img = new Span <byte>((void *)data.Scan0, data.Stride * data.Height);

                tempBuffer[j] = new FDataBuffer <byte>(device, physicalDevice, img.Length, VkBufferUsageFlags.TransferSrc,
                                                       VkSharingMode.Exclusive);

                Span <byte> buffer = tempBuffer[j].Map();
                for (int i = 0; i < img.Length; i += 4)
                {
                    buffer[i + 2] = img[i];
                    buffer[i + 1] = img[i + 1];
                    buffer[i]     = img[i + 2];
                    buffer[i + 3] = img[i + 3];
                }
                buffer = tempBuffer[j].UnMap();
            }

            VkImage        texture = VkImage.Null;
            VkDeviceMemory memory  = VkDeviceMemory.Null;

            VkImageCreateInfo createInfo = VkImageCreateInfo.New();

            createInfo.imageType     = VkImageType.Image2D;
            createInfo.extent.width  = width;
            createInfo.extent.height = height;
            createInfo.extent.depth  = 1;
            createInfo.mipLevels     = mipLevels;
            createInfo.arrayLayers   = (uint)paths.Length;
            createInfo.format        = VkFormat.R8g8b8a8Unorm;
            createInfo.tiling        = VkImageTiling.Optimal;
            createInfo.initialLayout = VkImageLayout.Undefined;
            createInfo.usage         = VkImageUsageFlags.TransferDst | VkImageUsageFlags.Sampled | VkImageUsageFlags.TransferSrc;
            createInfo.sharingMode   = VkSharingMode.Exclusive;
            createInfo.samples       = VkSampleCountFlags.Count1;

            Assert(vkCreateImage(device, &createInfo, null, &texture));

            VkMemoryRequirements memoryRequirements;

            vkGetImageMemoryRequirements(device, texture, &memoryRequirements);

            VkPhysicalDeviceMemoryProperties memoryProperties = new VkPhysicalDeviceMemoryProperties();

            vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties);

            VkMemoryAllocateInfo allocateInfo = VkMemoryAllocateInfo.New();

            allocateInfo.allocationSize  = memoryRequirements.size;
            allocateInfo.memoryTypeIndex = FDataBuffer <byte> .SelectMemoryType(memoryProperties, memoryRequirements.memoryTypeBits,
                                                                                VkMemoryPropertyFlags.DeviceLocal);

            Assert(vkAllocateMemory(device, &allocateInfo, null, &memory));

            vkBindImageMemory(device, texture, memory, 0);

            VkCommandBufferAllocateInfo pAllocateInfo = VkCommandBufferAllocateInfo.New();

            pAllocateInfo.commandPool        = CommandPoolManager.GetPool(cmdPoolID);
            pAllocateInfo.level              = VkCommandBufferLevel.Primary;
            pAllocateInfo.commandBufferCount = 1;

            VkCommandBuffer cmdBuffer = VkCommandBuffer.Null;

            Assert(vkAllocateCommandBuffers(device, &pAllocateInfo, &cmdBuffer));

            VkCommandBufferBeginInfo beginInfo = VkCommandBufferBeginInfo.New();

            beginInfo.flags = VkCommandBufferUsageFlags.OneTimeSubmit;

            Assert(vkBeginCommandBuffer(cmdBuffer, &beginInfo));

            VkImageMemoryBarrier imageMemoryBarrier = VkImageMemoryBarrier.New();

            imageMemoryBarrier.srcAccessMask       = VkAccessFlags.None;
            imageMemoryBarrier.dstAccessMask       = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite;
            imageMemoryBarrier.oldLayout           = VkImageLayout.Undefined;
            imageMemoryBarrier.newLayout           = VkImageLayout.TransferDstOptimal;
            imageMemoryBarrier.srcQueueFamilyIndex = VulkanNative.QueueFamilyIgnored;
            imageMemoryBarrier.dstQueueFamilyIndex = VulkanNative.QueueFamilyIgnored;
            imageMemoryBarrier.image            = texture;
            imageMemoryBarrier.subresourceRange = new VkImageSubresourceRange()
            {
                baseMipLevel   = 0,
                levelCount     = mipLevels,
                baseArrayLayer = 0,
                layerCount     = (uint)paths.Length,
                aspectMask     = VkImageAspectFlags.Color
            };

            vkCmdPipelineBarrier(cmdBuffer, VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.AllCommands, VkDependencyFlags.ByRegion,
                                 0, null, 0, null, 1, &imageMemoryBarrier);

            for (int j = 0; j < tempBuffer.Length; j++)
            {
                VkBufferImageCopy region = new VkBufferImageCopy();
                region.bufferOffset      = 0;
                region.bufferRowLength   = 0;
                region.bufferImageHeight = 0;

                region.imageSubresource.aspectMask     = VkImageAspectFlags.Color;
                region.imageSubresource.mipLevel       = 0;
                region.imageSubresource.baseArrayLayer = (uint)j;
                region.imageSubresource.layerCount     = 1;

                region.imageOffset = new VkOffset3D();
                region.imageExtent = new VkExtent3D()
                {
                    width = width, height = height, depth = 1
                };

                vkCmdCopyBufferToImage(cmdBuffer, tempBuffer[j].Buffer, texture, VkImageLayout.TransferDstOptimal, 1, &region);
            }

            imageMemoryBarrier.oldLayout = VkImageLayout.TransferDstOptimal;
            imageMemoryBarrier.newLayout = VkImageLayout.ShaderReadOnlyOptimal;

            vkCmdPipelineBarrier(cmdBuffer, VkPipelineStageFlags.AllCommands, VkPipelineStageFlags.AllCommands, VkDependencyFlags.ByRegion,
                                 0, null, 0, null, 1, &imageMemoryBarrier);

            Assert(vkEndCommandBuffer(cmdBuffer));

            VkSubmitInfo submitInfo = VkSubmitInfo.New();

            submitInfo.commandBufferCount = 1;
            submitInfo.pCommandBuffers    = &cmdBuffer;

            Assert(vkQueueSubmit(queue, 1, &submitInfo, VkFence.Null));
            Assert(vkQueueWaitIdle(queue));
            vkFreeCommandBuffers(device, CommandPoolManager.GetPool(cmdPoolID), 1, &cmdBuffer);

            return(texture);
        }
Ejemplo n.º 8
0
        public static VkImageCreateInfo imageCreateInfo()
        {
            VkImageCreateInfo imageCreateInfo = VkImageCreateInfo.New();

            return(imageCreateInfo);
        }
Ejemplo n.º 9
0
        public VkTexture2D(
            VkDevice device,
            VkPhysicalDevice physicalDevice,
            VkDeviceMemoryManager memoryManager,
            VkRenderContext rc,
            int mipLevels,
            int width,
            int height,
            PixelFormat veldridFormat,
            DeviceTextureCreateOptions createOptions)
        {
            _device         = device;
            _physicalDevice = physicalDevice;
            _memoryManager  = memoryManager;
            _rc             = rc;

            MipLevels      = mipLevels;
            _width         = width;
            _height        = height;
            _createOptions = createOptions;
            if (createOptions == DeviceTextureCreateOptions.DepthStencil)
            {
                Format = VkFormat.D16Unorm;
            }
            else
            {
                Format = VkFormats.VeldridToVkPixelFormat(veldridFormat);
            }

            _veldridFormat = veldridFormat;

            VkImageCreateInfo imageCI = VkImageCreateInfo.New();

            imageCI.mipLevels     = (uint)mipLevels;
            imageCI.arrayLayers   = 1;
            imageCI.imageType     = VkImageType.Image2D;
            imageCI.extent.width  = (uint)width;
            imageCI.extent.height = (uint)height;
            imageCI.extent.depth  = 1;
            imageCI.initialLayout = VkImageLayout.Preinitialized; // TODO: Use proper VkImageLayout values and transitions.
            imageCI.usage         = VkImageUsageFlags.TransferDst | VkImageUsageFlags.Sampled;
            if (createOptions == DeviceTextureCreateOptions.RenderTarget)
            {
                imageCI.usage |= VkImageUsageFlags.ColorAttachment;
            }
            else if (createOptions == DeviceTextureCreateOptions.DepthStencil)
            {
                imageCI.usage |= VkImageUsageFlags.DepthStencilAttachment;
            }
            imageCI.tiling = createOptions == DeviceTextureCreateOptions.DepthStencil ? VkImageTiling.Optimal : VkImageTiling.Optimal;
            imageCI.format = Format;

            imageCI.samples = VkSampleCountFlags.Count1;

            VkResult result = vkCreateImage(device, ref imageCI, null, out _image);

            CheckResult(result);

            vkGetImageMemoryRequirements(_device, _image, out VkMemoryRequirements memoryRequirements);

            VkMemoryBlock memoryToken = memoryManager.Allocate(
                FindMemoryType(
                    _physicalDevice,
                    memoryRequirements.memoryTypeBits,
                    VkMemoryPropertyFlags.DeviceLocal),
                memoryRequirements.size,
                memoryRequirements.alignment);

            _memory = memoryToken;
            vkBindImageMemory(_device, _image, _memory.DeviceMemory, _memory.Offset);
        }
Ejemplo n.º 10
0
        internal VkTexture(VkGraphicsDevice gd, ref TextureDescription description)
        {
            _gd         = gd;
            Width       = description.Width;
            Height      = description.Height;
            Depth       = description.Depth;
            MipLevels   = description.MipLevels;
            ArrayLayers = description.ArrayLayers;
            bool isCubemap = ((description.Usage) & TextureUsage.Cubemap) == TextureUsage.Cubemap;

            _actualImageArrayLayers = isCubemap
                ? 6 * ArrayLayers
                : ArrayLayers;
            Format        = description.Format;
            Usage         = description.Usage;
            SampleCount   = description.SampleCount;
            VkSampleCount = VkFormats.VdToVkSampleCount(SampleCount);
            VkFormat      = VkFormats.VdToVkPixelFormat(Format, (description.Usage & TextureUsage.DepthStencil) == TextureUsage.DepthStencil);

            VkImageCreateInfo imageCI = VkImageCreateInfo.New();

            imageCI.mipLevels     = MipLevels;
            imageCI.arrayLayers   = _actualImageArrayLayers;
            imageCI.imageType     = Depth == 1 ? VkImageType.Image2D : VkImageType.Image3D;
            imageCI.extent.width  = Width;
            imageCI.extent.height = Height;
            imageCI.extent.depth  = Depth;
            imageCI.initialLayout = VkImageLayout.Preinitialized;
            imageCI.usage         = VkImageUsageFlags.TransferDst | VkImageUsageFlags.TransferSrc;
            bool isDepthStencil = (description.Usage & TextureUsage.DepthStencil) == TextureUsage.DepthStencil;

            if ((description.Usage & TextureUsage.Sampled) == TextureUsage.Sampled)
            {
                imageCI.usage |= VkImageUsageFlags.Sampled;
            }
            if (isDepthStencil)
            {
                imageCI.usage |= VkImageUsageFlags.DepthStencilAttachment;
            }
            if ((description.Usage & TextureUsage.RenderTarget) == TextureUsage.RenderTarget)
            {
                imageCI.usage |= VkImageUsageFlags.ColorAttachment;
            }
            if ((description.Usage & TextureUsage.Storage) == TextureUsage.Storage)
            {
                imageCI.usage |= VkImageUsageFlags.Storage;
            }

            bool isStaging = (Usage & TextureUsage.Staging) == TextureUsage.Staging;

            imageCI.tiling = isStaging ? VkImageTiling.Linear : VkImageTiling.Optimal;
            imageCI.format = VkFormat;

            imageCI.samples = VkSampleCount;
            if (isCubemap)
            {
                imageCI.flags = VkImageCreateFlags.CubeCompatible;
            }

            uint subresourceCount = MipLevels * _actualImageArrayLayers;

            if (!isStaging)
            {
                VkResult result = vkCreateImage(gd.Device, ref imageCI, null, out _optimalImage);
                CheckResult(result);

                vkGetImageMemoryRequirements(gd.Device, _optimalImage, out VkMemoryRequirements memoryRequirements);

                VkMemoryBlock memoryToken = gd.MemoryManager.Allocate(
                    gd.PhysicalDeviceMemProperties,
                    memoryRequirements.memoryTypeBits,
                    VkMemoryPropertyFlags.DeviceLocal,
                    false,
                    memoryRequirements.size,
                    memoryRequirements.alignment);
                _optimalMemory = memoryToken;
                vkBindImageMemory(gd.Device, _optimalImage, _optimalMemory.DeviceMemory, _optimalMemory.Offset);
            }
            else
            {
                // Linear images must have one array layer and mip level.
                imageCI.arrayLayers = 1;
                imageCI.mipLevels   = 1;

                _stagingImages   = new VkImage[subresourceCount];
                _stagingMemories = new VkMemoryBlock[subresourceCount];
                for (uint arrayLayer = 0; arrayLayer < ArrayLayers; arrayLayer++)
                {
                    for (uint level = 0; level < MipLevels; level++)
                    {
                        uint subresource = CalculateSubresource(level, arrayLayer);
                        Util.GetMipDimensions(
                            this,
                            level,
                            out imageCI.extent.width,
                            out imageCI.extent.height,
                            out imageCI.extent.depth);

                        VkResult result = vkCreateImage(gd.Device, ref imageCI, null, out _stagingImages[subresource]);
                        CheckResult(result);

                        vkGetImageMemoryRequirements(
                            gd.Device,
                            _stagingImages[subresource],
                            out VkMemoryRequirements memoryRequirements);

                        VkMemoryBlock memoryToken = gd.MemoryManager.Allocate(
                            gd.PhysicalDeviceMemProperties,
                            memoryRequirements.memoryTypeBits,
                            VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent,
                            true,
                            memoryRequirements.size,
                            memoryRequirements.alignment);
                        _stagingMemories[subresource] = memoryToken;

                        result = vkBindImageMemory(
                            gd.Device,
                            _stagingImages[subresource],
                            memoryToken.DeviceMemory,
                            memoryToken.Offset);
                        CheckResult(result);
                    }
                }
            }

            _imageLayouts = new VkImageLayout[subresourceCount];
            for (int i = 0; i < _imageLayouts.Length; i++)
            {
                _imageLayouts[i] = VkImageLayout.Preinitialized;
            }
        }
Ejemplo n.º 11
0
        internal VkTexture(VkGraphicsDevice gd, ref TextureDescription description)
        {
            _gd         = gd;
            Width       = description.Width;
            Height      = description.Height;
            Depth       = description.Depth;
            MipLevels   = description.MipLevels;
            ArrayLayers = description.ArrayLayers;
            Format      = description.Format;
            Usage       = description.Usage;
            if ((description.Usage & TextureUsage.DepthStencil) == TextureUsage.DepthStencil)
            {
                if (Format != PixelFormat.R16_UNorm && Format != PixelFormat.R32_Float)
                {
                    throw new NotImplementedException("The only supported depth texture formats are R16_UInt and R32_Float.");
                }
                if (Format == PixelFormat.R16_UNorm)
                {
                    VkFormat = VkFormat.D16Unorm;
                }
                else
                {
                    VkFormat = VkFormat.D32Sfloat;
                }
            }
            else
            {
                VkFormat = VkFormats.VdToVkPixelFormat(Format);
            }

            VkImageCreateInfo imageCI = VkImageCreateInfo.New();

            imageCI.mipLevels     = MipLevels;
            imageCI.arrayLayers   = description.ArrayLayers;
            imageCI.imageType     = Depth == 1 ? VkImageType.Image2D : VkImageType.Image3D;
            imageCI.extent.width  = Width;
            imageCI.extent.height = Height;
            imageCI.extent.depth  = Depth;
            imageCI.initialLayout = VkImageLayout.Preinitialized;
            imageCI.usage         = VkImageUsageFlags.TransferDst | VkImageUsageFlags.Sampled;
            bool isDepthStencil = (description.Usage & TextureUsage.DepthStencil) == TextureUsage.DepthStencil;

            if ((description.Usage & TextureUsage.Sampled) == TextureUsage.Sampled)
            {
                imageCI.usage |= VkImageUsageFlags.Sampled;
            }
            if (isDepthStencil)
            {
                imageCI.usage |= VkImageUsageFlags.DepthStencilAttachment;
            }
            imageCI.tiling = VkImageTiling.Optimal;
            imageCI.format = VkFormat;

            imageCI.samples = VkSampleCountFlags.Count1;
            if ((Usage & TextureUsage.Cubemap) == TextureUsage.Cubemap)
            {
                imageCI.flags        = VkImageCreateFlags.CubeCompatible;
                imageCI.arrayLayers *= 6;
            }

            VkResult result = vkCreateImage(gd.Device, ref imageCI, null, out _image);

            CheckResult(result);
            ImageLayouts = new VkImageLayout[MipLevels];
            for (int i = 0; i < MipLevels; i++)
            {
                ImageLayouts[i] = VkImageLayout.Preinitialized;
            }

            vkGetImageMemoryRequirements(gd.Device, _image, out VkMemoryRequirements memoryRequirements);

            VkMemoryBlock memoryToken = gd.MemoryManager.Allocate(
                gd.PhysicalDeviceMemProperties,
                memoryRequirements.memoryTypeBits,
                VkMemoryPropertyFlags.DeviceLocal,
                false,
                memoryRequirements.size,
                memoryRequirements.alignment);

            _memory = memoryToken;
            vkBindImageMemory(gd.Device, _image, _memory.DeviceMemory, _memory.Offset);
        }
Ejemplo n.º 12
0
        internal VkTexture(VkGraphicsDevice gd, ref TextureDescription description)
        {
            _gd         = gd;
            _width      = description.Width;
            _height     = description.Height;
            _depth      = description.Depth;
            MipLevels   = description.MipLevels;
            ArrayLayers = description.ArrayLayers;
            bool isCubemap = ((description.Usage) & TextureUsage.Cubemap) == TextureUsage.Cubemap;

            _actualImageArrayLayers = isCubemap
                ? 6 * ArrayLayers
                : ArrayLayers;
            _format       = description.Format;
            Usage         = description.Usage;
            Type          = description.Type;
            SampleCount   = description.SampleCount;
            VkSampleCount = VkFormats.VdToVkSampleCount(SampleCount);
            VkFormat      = VkFormats.VdToVkPixelFormat(Format, (description.Usage & TextureUsage.DepthStencil) == TextureUsage.DepthStencil);

            bool isStaging = (Usage & TextureUsage.Staging) == TextureUsage.Staging;

            if (!isStaging)
            {
                VkImageCreateInfo imageCI = VkImageCreateInfo.New();
                imageCI.mipLevels     = MipLevels;
                imageCI.arrayLayers   = _actualImageArrayLayers;
                imageCI.imageType     = VkFormats.VdToVkTextureType(Type);
                imageCI.extent.width  = Width;
                imageCI.extent.height = Height;
                imageCI.extent.depth  = Depth;
                imageCI.initialLayout = VkImageLayout.Preinitialized;
                imageCI.usage         = VkFormats.VdToVkTextureUsage(Usage);
                imageCI.tiling        = isStaging ? VkImageTiling.Linear : VkImageTiling.Optimal;
                imageCI.format        = VkFormat;
                imageCI.flags         = VkImageCreateFlags.MutableFormat;

                imageCI.samples = VkSampleCount;
                if (isCubemap)
                {
                    imageCI.flags |= VkImageCreateFlags.CubeCompatible;
                }

                uint     subresourceCount = MipLevels * _actualImageArrayLayers * Depth;
                VkResult result           = vkCreateImage(gd.Device, ref imageCI, null, out _optimalImage);
                CheckResult(result);

                VkMemoryRequirements memoryRequirements;
                bool prefersDedicatedAllocation;
                if (_gd.GetImageMemoryRequirements2 != null)
                {
                    VkImageMemoryRequirementsInfo2KHR memReqsInfo2 = VkImageMemoryRequirementsInfo2KHR.New();
                    memReqsInfo2.image = _optimalImage;
                    VkMemoryRequirements2KHR         memReqs2      = VkMemoryRequirements2KHR.New();
                    VkMemoryDedicatedRequirementsKHR dedicatedReqs = VkMemoryDedicatedRequirementsKHR.New();
                    memReqs2.pNext = &dedicatedReqs;
                    _gd.GetImageMemoryRequirements2(_gd.Device, &memReqsInfo2, &memReqs2);
                    memoryRequirements         = memReqs2.memoryRequirements;
                    prefersDedicatedAllocation = dedicatedReqs.prefersDedicatedAllocation || dedicatedReqs.requiresDedicatedAllocation;
                }
                else
                {
                    vkGetImageMemoryRequirements(gd.Device, _optimalImage, out memoryRequirements);
                    prefersDedicatedAllocation = false;
                }

                VkMemoryBlock memoryToken = gd.MemoryManager.Allocate(
                    gd.PhysicalDeviceMemProperties,
                    memoryRequirements.memoryTypeBits,
                    VkMemoryPropertyFlags.DeviceLocal,
                    false,
                    memoryRequirements.size,
                    memoryRequirements.alignment,
                    prefersDedicatedAllocation,
                    _optimalImage,
                    Vulkan.VkBuffer.Null);
                _memoryBlock = memoryToken;
                result       = vkBindImageMemory(gd.Device, _optimalImage, _memoryBlock.DeviceMemory, _memoryBlock.Offset);
                CheckResult(result);

                _imageLayouts = new VkImageLayout[subresourceCount];
                for (int i = 0; i < _imageLayouts.Length; i++)
                {
                    _imageLayouts[i] = VkImageLayout.Preinitialized;
                }
            }
            else // isStaging
            {
                uint depthPitch = FormatHelpers.GetDepthPitch(
                    FormatHelpers.GetRowPitch(Width, Format),
                    Height,
                    Format);
                uint stagingSize = depthPitch * Depth;
                for (uint level = 1; level < MipLevels; level++)
                {
                    Util.GetMipDimensions(this, level, out uint mipWidth, out uint mipHeight, out uint mipDepth);

                    depthPitch = FormatHelpers.GetDepthPitch(
                        FormatHelpers.GetRowPitch(mipWidth, Format),
                        mipHeight,
                        Format);

                    stagingSize += depthPitch * mipDepth;
                }
                stagingSize *= ArrayLayers;

                VkBufferCreateInfo bufferCI = VkBufferCreateInfo.New();
                bufferCI.usage = VkBufferUsageFlags.TransferSrc | VkBufferUsageFlags.TransferDst;
                bufferCI.size  = stagingSize;
                VkResult result = vkCreateBuffer(_gd.Device, ref bufferCI, null, out _stagingBuffer);
                CheckResult(result);

                VkMemoryRequirements bufferMemReqs;
                bool prefersDedicatedAllocation;
                if (_gd.GetBufferMemoryRequirements2 != null)
                {
                    VkBufferMemoryRequirementsInfo2KHR memReqInfo2 = VkBufferMemoryRequirementsInfo2KHR.New();
                    memReqInfo2.buffer = _stagingBuffer;
                    VkMemoryRequirements2KHR         memReqs2      = VkMemoryRequirements2KHR.New();
                    VkMemoryDedicatedRequirementsKHR dedicatedReqs = VkMemoryDedicatedRequirementsKHR.New();
                    memReqs2.pNext = &dedicatedReqs;
                    _gd.GetBufferMemoryRequirements2(_gd.Device, &memReqInfo2, &memReqs2);
                    bufferMemReqs = memReqs2.memoryRequirements;
                    prefersDedicatedAllocation = dedicatedReqs.prefersDedicatedAllocation || dedicatedReqs.requiresDedicatedAllocation;
                }
                else
                {
                    vkGetBufferMemoryRequirements(gd.Device, _stagingBuffer, out bufferMemReqs);
                    prefersDedicatedAllocation = false;
                }

                // Use "host cached" memory when available, for better performance of GPU -> CPU transfers
                var propertyFlags = VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent | VkMemoryPropertyFlags.HostCached;
                if (!TryFindMemoryType(_gd.PhysicalDeviceMemProperties, bufferMemReqs.memoryTypeBits, propertyFlags, out _))
                {
                    propertyFlags ^= VkMemoryPropertyFlags.HostCached;
                }
                _memoryBlock = _gd.MemoryManager.Allocate(
                    _gd.PhysicalDeviceMemProperties,
                    bufferMemReqs.memoryTypeBits,
                    propertyFlags,
                    true,
                    bufferMemReqs.size,
                    bufferMemReqs.alignment,
                    prefersDedicatedAllocation,
                    VkImage.Null,
                    _stagingBuffer);

                result = vkBindBufferMemory(_gd.Device, _stagingBuffer, _memoryBlock.DeviceMemory, _memoryBlock.Offset);
                CheckResult(result);
            }

            ClearIfRenderTarget();
            TransitionIfSampled();
            RefCount = new ResourceRefCount(RefCountedDispose);
        }