Beispiel #1
0
        public unsafe static Texture Create2D(uint w, uint h, VkFormat format, IntPtr tex2DDataPtr, bool dynamic = false)
        {
            var texture = new Texture
            {
                extent    = new VkExtent3D(w, h, 1),
                mipLevels = 1,
                format    = format
            };

            texture.image = Image.Create(w, h, VkImageCreateFlags.None, 1, 1, format, VkSampleCountFlags.Count1, VkImageUsageFlags.TransferDst | VkImageUsageFlags.Sampled);

            ulong totalBytes = texture.image.AllocationSize;

            using (Buffer stagingBuffer = Buffer.CreateStagingBuffer(totalBytes, tex2DDataPtr))
            {
                VkBufferImageCopy bufferCopyRegion = new VkBufferImageCopy
                {
                    imageSubresource = new VkImageSubresourceLayers
                    {
                        aspectMask     = VkImageAspectFlags.Color,
                        mipLevel       = 0,
                        baseArrayLayer = 0,
                        layerCount     = 1,
                    },

                    imageExtent  = new VkExtent3D(w, h, 1),
                    bufferOffset = 0
                };

                // The sub resource range describes the regions of the image we will be transition
                var           subresourceRange = new VkImageSubresourceRange(VkImageAspectFlags.Color, 0, 1, 0, 1);
                CommandBuffer copyCmd          = Graphics.BeginPrimaryCmd();
                copyCmd.SetImageLayout(texture.image, VkImageAspectFlags.Color, VkImageLayout.Undefined, VkImageLayout.TransferDstOptimal, subresourceRange);
                copyCmd.CopyBufferToImage(stagingBuffer, texture.image, VkImageLayout.TransferDstOptimal, ref bufferCopyRegion);
                copyCmd.SetImageLayout(texture.image, VkImageAspectFlags.Color, VkImageLayout.TransferDstOptimal, texture.imageLayout, subresourceRange);
                Graphics.EndPrimaryCmd(copyCmd);

                // Change texture image layout to shader read after all mip levels have been copied
                texture.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
            }

            texture.imageView = ImageView.Create(texture.image, VkImageViewType.Image2D, format, VkImageAspectFlags.Color, 0, texture.mipLevels);
            texture.sampler   = new Sampler(VkFilter.Linear, VkSamplerMipmapMode.Linear, VkSamplerAddressMode.Repeat, texture.mipLevels, Device.Features.samplerAnisotropy == true);
            texture.UpdateDescriptor();
            return(texture);
        }
Beispiel #2
0
        public unsafe void SetImageData(MipmapLevel[] imageData)
        {
            this.imageData = imageData;
            this.extent    = new VkExtent3D(imageData[0].Width, imageData[0].Height, 1);
            mipLevels      = (uint)imageData.Length;
            layers         = (uint)imageData[0].ArrayElements.Length;
            faceCount      = (uint)imageData[0].ArrayElements[0].Faces.Length;

            ulong totalSize = 0;

            foreach (var mip in imageData)
            {
                totalSize += mip.TotalSize * layers * faceCount;
            }

            Buffer stagingBuffer = Buffer.CreateStagingBuffer(totalSize, IntPtr.Zero);

            image = Image.Create(width, height, imageCreateFlags, layers * faceCount, mipLevels, format, VkSampleCountFlags.Count1, VkImageUsageFlags.TransferDst | VkImageUsageFlags.Sampled);

            IntPtr mapped = stagingBuffer.Map();

            // Setup buffer copy regions for each face including all of it's miplevels
            Span <VkBufferImageCopy> bufferCopyRegions = stackalloc VkBufferImageCopy[(int)(mipLevels * layers * faceCount)];
            uint offset = 0;
            int  index  = 0;

            for (int layer = 0; layer < layers; layer++)
            {
                for (int face = 0; face < faceCount; face++)
                {
                    for (uint level = 0; level < mipLevels; level++)
                    {
                        var mipLevel     = imageData[level];
                        var layerElement = mipLevel.ArrayElements[layer];
                        var faceElement  = layerElement.Faces[face];

                        Unsafe.CopyBlock((void *)(mapped + (int)offset), Unsafe.AsPointer(ref faceElement.Data[0]), (uint)faceElement.Data.Length);

                        VkBufferImageCopy bufferCopyRegion = new VkBufferImageCopy
                        {
                            imageSubresource = new VkImageSubresourceLayers
                            {
                                aspectMask     = VkImageAspectFlags.Color,
                                mipLevel       = level,
                                baseArrayLayer = (uint)(layer * faceCount + face),
                                layerCount     = 1
                            },

                            imageExtent  = new VkExtent3D(mipLevel.Width, mipLevel.Height, mipLevel.Depth),
                            bufferOffset = offset
                        };

                        bufferCopyRegions[index++] = bufferCopyRegion;
                        offset += (uint)faceElement.Data.Length;
                    }
                }
            }


            stagingBuffer.Unmap();

            var subresourceRange = new VkImageSubresourceRange(VkImageAspectFlags.Color, 0, mipLevels, 0, layers * faceCount);

            CommandBuffer copyCmd = Graphics.BeginPrimaryCmd();

            copyCmd.SetImageLayout(image, VkImageAspectFlags.Color, VkImageLayout.Undefined, VkImageLayout.TransferDstOptimal, subresourceRange);
            copyCmd.CopyBufferToImage(stagingBuffer, image, VkImageLayout.TransferDstOptimal, bufferCopyRegions);
            copyCmd.SetImageLayout(image, VkImageAspectFlags.Color, VkImageLayout.TransferDstOptimal, imageLayout, subresourceRange);
            Graphics.EndPrimaryCmd(copyCmd);

            imageLayout = VkImageLayout.ShaderReadOnlyOptimal;

            stagingBuffer.Dispose();

            imageView = ImageView.Create(image, ImageViewType, format, VkImageAspectFlags.Color, 0, mipLevels, 0, layers);
            sampler   = new Sampler(VkFilter.Linear, VkSamplerMipmapMode.Linear, samplerAddressMode, mipLevels, Device.Features.samplerAnisotropy == true, borderColor);

            UpdateDescriptor();
        }