Esempio n. 1
0
        public unsafe DepthImage(uint width, uint height, PhysicalDevice physicalDevice, Device device)
        {
            _width          = width;
            _height         = height;
            _vk             = VkUtil.Vk;
            _physicalDevice = physicalDevice;
            _device         = device;

            Format = FindFormat(FormatFeatureFlags.FormatFeatureDepthStencilAttachmentBit, Format.D32SfloatS8Uint, Format.D24UnormS8Uint);

            ImageCreateInfo imageCreateInfo = VkInit.ImageCreateInfo(ImageType.ImageType2D, Format, _width, _height);

            VkUtil.AssertVulkan(_vk.CreateImage(_device, imageCreateInfo, null, out _image));

            _vk.GetImageMemoryRequirements(_device, _image, out MemoryRequirements memReqs);
            _vk.GetPhysicalDeviceMemoryProperties(_physicalDevice, out PhysicalDeviceMemoryProperties memoryProperties);
            uint index = VkUtil.FindMemoryTypeIndex(memReqs.MemoryTypeBits, MemoryPropertyFlags.MemoryPropertyDeviceLocalBit, memoryProperties);

            MemoryAllocateInfo memoryAllocateInfo = VkInit.MemoryAllocateInfo(memReqs.Size, index);

            VkUtil.AssertVulkan(_vk.AllocateMemory(_device, memoryAllocateInfo, null, out _memory));
            VkUtil.AssertVulkan(_vk.BindImageMemory(_device, _image, _memory, 0));

            ImageViewCreateInfo imageViewCreateInfo = VkInit.ImageViewCreateInfo(Format, _image, ImageAspectFlags.ImageAspectDepthBit);

            VkUtil.AssertVulkan(_vk.CreateImageView(_device, imageViewCreateInfo, null, out _imageView));
        }
Esempio n. 2
0
        public FrameBufferAttachment CreateAttachment(string AttachmentLookupID, Format myFormat, ImageType myType, ImageViewType view2D, ImageUsageFlags myImageFlag, ImageAspectFlags color, ImageTiling myTiles, SampleCountFlags mySampleCount, uint levelCount, uint layercount)
        {        //TODO: Write exception class
            if (Initialized)
            {
                throw new Exception("Attempted to add attachment to initialized Framebuffer!");
            }
            if (myAttachments.ContainsKey(AttachmentLookupID))
            {
                throw new Exception("A framebuffer attachment with ID: " + AttachmentLookupID + " was added to frame buffer twice.");
            }
            ImageCreateInfo myInfo = new ImageCreateInfo()
            {
                ImageType = myType, MipLevels = 1, Format = myFormat, Extent = new Extent3D()
                {
                    Width = myFramebufferInfo.Width, Height = myFramebufferInfo.Height, Depth = 1
                }, ArrayLayers = layercount, Samples = mySampleCount, Tiling = myTiles, Usage = myImageFlag
            };

            myImage = new Image(myInfo);
            var Return = this.CreateAttachment(AttachmentLookupID, myFormat, view2D, myImage, color, levelCount, layercount);

            myAttachments[AttachmentLookupID] = Return;
            myInfo.Dispose(false);
            return(Return);
        }
        public Image(VulkanPhysicalDevice myDevice, ImageCreateInfo pCreateInfo, AllocationCallbacks pAllocator = null)
        {
            this.Device = myDevice;
            Result result;

            unsafe
            {
                fixed(UInt64 *ptrpImage = &this.m)
                {
                    result = Interop.NativeMethods.vkCreateImage(myDevice.LogicalDevice.m, pCreateInfo != null ? pCreateInfo.m : (Interop.ImageCreateInfo *) default(IntPtr), pAllocator != null ? pAllocator.m : null, ptrpImage);
                }

                if (result != Result.Success)
                {
                    throw new ResultException(result);
                }
            }

            MemoryRequirements myRequirements = GetImageMemoryRequirements();

            MemoryAllocateInfo MemInfo = new MemoryAllocateInfo();

            MemInfo.AllocationSize = myRequirements.Size;


            MemInfo.MemoryTypeIndex = myDevice.GetMemoryIndexFromProperty(myRequirements.MemoryTypeBits, MemoryPropertyFlags.DeviceLocal);



            deviceMemory = new DeviceMemory(myDevice.LogicalDevice, MemInfo);
            BindImageMemory(deviceMemory, 0);
        }
Esempio n. 4
0
        public void CreateDepth()
        {
            ImageCreateInfo imageInfo = new ImageCreateInfo
            {
                ImageType = ImageType.Image2D,
                Format    = Format.D16Unorm,
                Extent    = new Extent3D
                {
                    Width  = BackBufferWidth,
                    Height = BackBufferHeight,
                    Depth  = 1,
                },
                MipLevels   = 1,
                ArrayLayers = 1,
                Samples     = (uint)SampleCountFlags.Count1,
                Tiling      = ImageTiling.Optimal,
                Usage       = (uint)ImageUsageFlags.DepthStencilAttachment,
                Flags       = 0,
            };

            Image image = Device.CreateImage(imageInfo, null);
            MemoryRequirements memReq = Device.GetImageMemoryRequirements(image);

            uint memTypeIndex;

            if (!TryGetMemoryTypeFromProperties(memReq.MemoryTypeBits, 0, out memTypeIndex))
            {
                throw new Exception("Failed to create back buffer");
            }

            MemoryAllocateInfo allocInfo = new MemoryAllocateInfo
            {
                AllocationSize  = 0,
                MemoryTypeIndex = memTypeIndex,
            };

            DeviceMemory imageMem = Device.AllocateMemory(allocInfo, null);

            Device.BindImageMemory(image, imageMem, 0);

            SetImageLayout(image, ImageAspectFlags.Depth, ImageLayout.Undefined, ImageLayout.DepthStencilAttachmentOptimal, 0);

            ImageViewCreateInfo imageViewInfo = new ImageViewCreateInfo
            {
                Image            = image,
                Format           = imageInfo.Format,
                SubresourceRange = new ImageSubresourceRange
                {
                    AspectMask     = (uint)ImageAspectFlags.Depth,
                    BaseMipLevel   = 0,
                    LevelCount     = 1,
                    BaseArrayLayer = 0,
                    LayerCount     = 1,
                },
                Flags    = 0,
                ViewType = ImageViewType.View2D,
            };

            ImageView imageView = Device.CreateImageView(imageViewInfo, null);
        }
Esempio n. 5
0
        public void CmdDraw()
        {
            var renderPassCreateInfo = new RenderPassCreateInfo(new[] { new SubpassDescription(
                                                                            new[] { new AttachmentReference(0, ImageLayout.ColorAttachmentOptimal) }) },
                                                                new[] { new AttachmentDescription {
                                                                            Format = Format.B8G8R8A8UNorm, Samples = SampleCounts.Count1
                                                                        } });
            var imageCreateInfo = new ImageCreateInfo
            {
                Usage       = ImageUsages.ColorAttachment,
                Format      = Format.B8G8R8A8UNorm,
                Extent      = new Extent3D(2, 2, 1),
                ImageType   = ImageType.Image2D,
                MipLevels   = 1,
                ArrayLayers = 1,
                Samples     = SampleCounts.Count1
            };
            var imageViewCreateInfo = new ImageViewCreateInfo(
                Format.B8G8R8A8UNorm,
                new ImageSubresourceRange(ImageAspects.Color, 0, 1, 0, 1));

            using (ShaderModule vertexShader = Device.CreateShaderModule(new ShaderModuleCreateInfo(ReadAllBytes("Shader.vert.spv"))))
                using (ShaderModule fragmentShader = Device.CreateShaderModule(new ShaderModuleCreateInfo(ReadAllBytes("Shader.frag.spv"))))
                    using (PipelineLayout pipelineLayout = Device.CreatePipelineLayout())
                        using (RenderPass renderPass = Device.CreateRenderPass(renderPassCreateInfo))
                            using (Image image = Device.CreateImage(imageCreateInfo))
                            {
                                MemoryRequirements imageMemReq = image.GetMemoryRequirements();
                                int memTypeIndex = PhysicalDeviceMemoryProperties.MemoryTypes.IndexOf(imageMemReq.MemoryTypeBits, MemoryProperties.DeviceLocal);
                                using (DeviceMemory imageMemory = Device.AllocateMemory(new MemoryAllocateInfo(imageMemReq.Size, memTypeIndex)))
                                {
                                    image.BindMemory(imageMemory);
                                    using (ImageView imageView = image.CreateView(imageViewCreateInfo))
                                        using (Framebuffer framebuffer = renderPass.CreateFramebuffer(new FramebufferCreateInfo(new[] { imageView }, 2, 2)))
                                            using (Pipeline pipeline = Device.CreateGraphicsPipeline(new GraphicsPipelineCreateInfo(
                                                                                                         pipelineLayout,
                                                                                                         renderPass,
                                                                                                         0,
                                                                                                         new[]
                                            {
                                                new PipelineShaderStageCreateInfo(ShaderStages.Vertex, vertexShader, "main"),
                                                new PipelineShaderStageCreateInfo(ShaderStages.Fragment, fragmentShader, "main")
                                            },
                                                                                                         new PipelineInputAssemblyStateCreateInfo(),
                                                                                                         new PipelineVertexInputStateCreateInfo(),
                                                                                                         new PipelineRasterizationStateCreateInfo {
                                                RasterizerDiscardEnable = true, LineWidth = 1.0f
                                            })))
                                            {
                                                CommandBuffer.Begin();
                                                CommandBuffer.CmdBeginRenderPass(new RenderPassBeginInfo(framebuffer, new Rect2D(0, 0, 2, 2)));
                                                CommandBuffer.CmdBindPipeline(PipelineBindPoint.Graphics, pipeline);
                                                CommandBuffer.CmdDraw(3);
                                                CommandBuffer.CmdEndRenderPass();
                                                CommandBuffer.End();
                                            }
                                }
                            }
        }
Esempio n. 6
0
        protected Image CreateTextureImage(Format imageFormat, uint width, uint height)
        {
            var size            = new Extent3D(width, height, 1);
            var usage           = ImageUsageFlags.TransferDst | ImageUsageFlags.Sampled;
            var createImageInfo = new ImageCreateInfo(ImageType.ImageType2d, imageFormat, size, 1, 1, SampleCountFlags.SampleCountFlags1, ImageTiling.Optimal, usage, SharingMode.Exclusive, null, ImageLayout.Preinitialized);

            return(device.CreateImage(createImageInfo));
        }
Esempio n. 7
0
        private unsafe void CreateImages()
        {
            _imageViews      = new Auto <DisposableImageView> [ImageCount];
            _fences          = new FenceHolder[ImageCount];
            _presentedImages = new PresentImageInfo[ImageCount];

            _nextImage = 0;
            var cbs = _gd.CommandBufferPool.Rent();

            var imageCreateInfo = new ImageCreateInfo
            {
                SType         = StructureType.ImageCreateInfo,
                ImageType     = ImageType.ImageType2D,
                Format        = Format,
                Extent        = new Extent3D((uint?)_width, (uint?)_height, 1),
                MipLevels     = 1,
                ArrayLayers   = 1,
                Samples       = SampleCountFlags.SampleCount1Bit,
                Tiling        = ImageTiling.Optimal,
                Usage         = ImageUsageFlags.ImageUsageColorAttachmentBit | ImageUsageFlags.ImageUsageTransferSrcBit | ImageUsageFlags.ImageUsageTransferDstBit,
                SharingMode   = SharingMode.Exclusive,
                InitialLayout = ImageLayout.Undefined,
                Flags         = ImageCreateFlags.ImageCreateMutableFormatBit
            };

            for (int i = 0; i < _images.Length; i++)
            {
                _gd.Api.CreateImage(_device, imageCreateInfo, null, out var image).ThrowOnError();
                _images[i] = new Auto <DisposableImage>(new DisposableImage(_gd.Api, _device, image));

                _gd.Api.GetImageMemoryRequirements(_device, image,
                                                   out var memoryRequirements);
                var allocation = _gd.MemoryAllocator.AllocateDeviceMemory(_physicalDevice, memoryRequirements, MemoryPropertyFlags.MemoryPropertyDeviceLocalBit);

                _imageSizes[i]   = allocation.Size;
                _imageOffsets[i] = allocation.Offset;

                _imageAllocationAuto[i] = new Auto <MemoryAllocation>(allocation);

                _gd.Api.BindImageMemory(_device, image, allocation.Memory, allocation.Offset);

                _imageViews[i] = CreateImageView(image, Format);

                Transition(
                    cbs.CommandBuffer,
                    image,
                    0,
                    0,
                    ImageLayout.Undefined,
                    ImageLayout.TransferSrcOptimal);

                _states[i] = new ImageState();
            }

            _gd.CommandBufferPool.Return(cbs);
        }
Esempio n. 8
0
        Image CreateImage(Format imageFormat, uint width, uint height)
        {
            // Images represent multidimensional - up to 3 - arrays of data which can be used for
            // various purposes (e.g. attachments, textures), by binding them to a graphics or
            // compute pipeline via descriptor sets, or by directly specifying them as parameters
            // to certain commands.

            var size            = new Extent3D(width, height, 1);
            var usage           = ImageUsageFlags.ColorAttachment | ImageUsageFlags.TransferSrc | ImageUsageFlags.TransferDst;
            var createImageInfo = new ImageCreateInfo(ImageType.ImageType2d, imageFormat, size, 1, 1, SampleCountFlags.SampleCountFlags1, ImageTiling.Optimal, usage, SharingMode.Exclusive, null, ImageLayout.Preinitialized);

            return(device.CreateImage(createImageInfo));
        }
Esempio n. 9
0
 private Image CreateImage(ImageCreateFlags flags = 0, ImageTiling tiling = ImageTiling.Optimal)
 {
     var createInfo = new ImageCreateInfo
     {
         ArrayLayers = 1,
         Extent = new Extent3D(DefaultWidth, DefaultHeight, 1),
         Format = Format.B8G8R8A8UNorm,
         ImageType = ImageType.Image2D,
         Usage = ImageUsages.TransferSrc | ImageUsages.Sampled,
         MipLevels = 1,
         Samples = SampleCounts.Count1,
         Flags = flags,
         Tiling = tiling
     };
     return Device.CreateImage(createInfo);
 }
Esempio n. 10
0
        public void CreateImage()
        {
            var createInfo = new ImageCreateInfo
            {
                ArrayLayers = 1,
                Extent      = new Extent3D(32, 32, 1),
                Format      = Format.R32UInt,
                ImageType   = ImageType.Image2D,
                Usage       = ImageUsages.TransferSrc,
                MipLevels   = 1,
                Samples     = SampleCounts.Count1
            };

            using (Device.CreateImage(createInfo)) { }
            using (Device.CreateImage(createInfo, CustomAllocator)) { }
        }
        private unsafe void CreateDepthBuffer()
        {
            var depthInfo = new ImageCreateInfo
            {
                SType         = StructureType.ImageCreateInfo,
                ImageType     = ImageType.ImageType2D,
                Format        = DepthFormat,
                Extent        = new Extent3D(this.SwapchainExtent.Width, this.SwapchainExtent.Height, 1),
                MipLevels     = 1,
                ArrayLayers   = 1,
                Samples       = SampleCountFlags.SampleCount1Bit,
                InitialLayout = ImageLayout.Undefined,
                Usage         = ImageUsageFlags.ImageUsageDepthStencilAttachmentBit,
                SharingMode   = SharingMode.Exclusive
            };

            var depthViewInfo = new ImageViewCreateInfo
            {
                SType            = StructureType.ImageViewCreateInfo,
                Format           = DepthFormat,
                Components       = new ComponentMapping(ComponentSwizzle.R, ComponentSwizzle.G, ComponentSwizzle.B, ComponentSwizzle.A),
                SubresourceRange = new ImageSubresourceRange(aspectMask: ImageAspectFlags.ImageAspectDepthBit, levelCount: 1, layerCount: 1),
                ViewType         = ImageViewType.ImageViewType2D
            };

            var allocInfo = new AllocationCreateInfo(usage: MemoryUsage.GPU_Only);

            var image = this.Allocator.CreateImage(depthInfo, allocInfo, out Allocation alloc);

            depthViewInfo.Image = image;

            ImageView view;
            var       res = VkApi.CreateImageView(this.Device, &depthViewInfo, null, &view);

            if (res != Result.Success)
            {
                throw new Exception("Unable to create depth image view!");
            }

            this.DepthBuffer.Image      = image;
            this.DepthBuffer.View       = view;
            this.DepthBuffer.Allocation = alloc;
        }
Esempio n. 12
0
        private unsafe void CreateImage()
        {
            // Create a new image
            var createInfo = new ImageCreateInfo
            {
                StructureType = StructureType.ImageCreateInfo,
                ArrayLayers = (uint)ArraySize,
                Extent = new Extent3D((uint)Width, (uint)Height, (uint)Depth),
                MipLevels = (uint)MipLevels,
                Samples = SampleCountFlags.Sample1,
                Format = NativeFormat,
                Flags = ImageCreateFlags.None,
                Tiling = ImageTiling.Optimal,
                InitialLayout = ImageLayout.Undefined
            };

            switch (Dimension)
            {
                case TextureDimension.Texture1D:
                    createInfo.ImageType = ImageType.Image1D;
                    break;
                case TextureDimension.Texture2D:
                    createInfo.ImageType = ImageType.Image2D;
                    break;
                case TextureDimension.Texture3D:
                    createInfo.ImageType = ImageType.Image3D;
                    break;
                case TextureDimension.TextureCube:
                    createInfo.ImageType = ImageType.Image2D;
                    createInfo.Flags |= ImageCreateFlags.CubeCompatible;
                    break;
            }

            // TODO VULKAN: Can we restrict more based on GraphicsResourceUsage? 
            createInfo.Usage |= ImageUsageFlags.TransferSource | ImageUsageFlags.TransferDestination;

            if (IsRenderTarget)
                createInfo.Usage |= ImageUsageFlags.ColorAttachment;

            if (IsDepthStencil)
                createInfo.Usage |= ImageUsageFlags.DepthStencilAttachment;

            if (IsShaderResource)
                createInfo.Usage |= ImageUsageFlags.Sampled; // TODO VULKAN: Input attachments

            var memoryProperties = MemoryPropertyFlags.DeviceLocal;

            // Create native image
            // TODO: Multisampling, flags, usage, etc.
            NativeImage = GraphicsDevice.NativeDevice.CreateImage(ref createInfo);

            // Allocate and bind memory
            MemoryRequirements memoryRequirements;
            GraphicsDevice.NativeDevice.GetImageMemoryRequirements(NativeImage, out memoryRequirements);

            AllocateMemory(memoryProperties, memoryRequirements);

            if (NativeMemory != DeviceMemory.Null)
            {
                GraphicsDevice.NativeDevice.BindImageMemory(NativeImage, NativeMemory, 0);
            }
        }
 public Image(ImageCreateInfo pCreateInfo) : this(VulkanRenderer.SelectedPhysicalDevice, pCreateInfo)
 {
 }
Esempio n. 14
0
        public unsafe void Initialize()
        {
            if (!InternalHandle.HasValue)
            {
                MipLevels = MipLevels != 0 ? MipLevels : (uint)Math.Floor(Math.Log(Math.Max(Size.Width, Size.Height), 2));

                var imageCreateInfo = new ImageCreateInfo
                {
                    SType         = StructureType.ImageCreateInfo,
                    ImageType     = ImageType.ImageType2D,
                    Format        = Format,
                    Extent        = new Extent3D((uint?)Size.Width, (uint?)Size.Height, 1),
                    MipLevels     = MipLevels,
                    ArrayLayers   = 1,
                    Samples       = SampleCountFlags.SampleCount1Bit,
                    Tiling        = Tiling,
                    Usage         = _imageUsageFlags,
                    SharingMode   = SharingMode.Exclusive,
                    InitialLayout = ImageLayout.Undefined,
                    Flags         = ImageCreateFlags.ImageCreateMutableFormatBit
                };

                _device.Api.CreateImage(_device.InternalHandle, imageCreateInfo, null, out var image).ThrowOnError();
                InternalHandle = image;

                _device.Api.GetImageMemoryRequirements(_device.InternalHandle, InternalHandle.Value,
                                                       out var memoryRequirements);

                var memoryAllocateInfo = new MemoryAllocateInfo
                {
                    SType           = StructureType.MemoryAllocateInfo,
                    AllocationSize  = memoryRequirements.Size,
                    MemoryTypeIndex = (uint)VulkanMemoryHelper.FindSuitableMemoryTypeIndex(
                        _physicalDevice,
                        memoryRequirements.MemoryTypeBits, MemoryPropertyFlags.MemoryPropertyDeviceLocalBit)
                };

                _device.Api.AllocateMemory(_device.InternalHandle, memoryAllocateInfo, null,
                                           out var imageMemory);

                _imageMemory = imageMemory;

                _device.Api.BindImageMemory(_device.InternalHandle, InternalHandle.Value, _imageMemory, 0);

                MemorySize = memoryRequirements.Size;

                var componentMapping = new ComponentMapping(
                    ComponentSwizzle.Identity,
                    ComponentSwizzle.Identity,
                    ComponentSwizzle.Identity,
                    ComponentSwizzle.Identity);

                AspectFlags = ImageAspectFlags.ImageAspectColorBit;

                var subresourceRange = new ImageSubresourceRange(AspectFlags, 0, MipLevels, 0, 1);

                var imageViewCreateInfo = new ImageViewCreateInfo
                {
                    SType            = StructureType.ImageViewCreateInfo,
                    Image            = InternalHandle.Value,
                    ViewType         = ImageViewType.ImageViewType2D,
                    Format           = Format,
                    Components       = componentMapping,
                    SubresourceRange = subresourceRange
                };

                _device.Api
                .CreateImageView(_device.InternalHandle, imageViewCreateInfo, null, out var imageView)
                .ThrowOnError();

                _imageView = imageView;

                _currentLayout = ImageLayout.Undefined;

                TransitionLayout(ImageLayout.ColorAttachmentOptimal, AccessFlags.AccessNoneKhr);
            }
        }
Esempio n. 15
0
 public unsafe Image CreateImage(ref ImageCreateInfo createInfo, AllocationCallbacks* allocator = null)
 {
     Image image;
     fixed (ImageCreateInfo* __createInfo__ = &createInfo)
     {
         vkCreateImage(this, __createInfo__, allocator, &image).CheckError();
     }
     return image;
 }
Esempio n. 16
0
        public unsafe TextureStorage(
            VulkanRenderer gd,
            PhysicalDevice physicalDevice,
            Device device,
            TextureCreateInfo info,
            float scaleFactor,
            Auto <MemoryAllocation> foreignAllocation = null)
        {
            _gd         = gd;
            _device     = device;
            _info       = info;
            ScaleFactor = scaleFactor;

            var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format);
            var levels = (uint)info.Levels;
            var layers = (uint)info.GetLayers();
            var depth  = (uint)(info.Target == Target.Texture3D ? info.Depth : 1);

            VkFormat = format;

            var type = info.Target.Convert();

            var extent = new Extent3D((uint)info.Width, (uint)info.Height, depth);

            var sampleCountFlags = ConvertToSampleCountFlags((uint)info.Samples);

            var usage = DefaultUsageFlags;

            if (info.Format.IsDepthOrStencil())
            {
                usage |= ImageUsageFlags.ImageUsageDepthStencilAttachmentBit;
            }
            else if (info.Format.IsRtColorCompatible())
            {
                usage |= ImageUsageFlags.ImageUsageColorAttachmentBit;
            }

            if (info.Format.IsImageCompatible())
            {
                usage |= ImageUsageFlags.ImageUsageStorageBit;
            }

            var flags = ImageCreateFlags.ImageCreateMutableFormatBit;

            // This flag causes mipmapped texture arrays to break on AMD GCN, so for that copy dependencies are forced for aliasing as cube.
            bool isCube         = info.Target == Target.Cubemap || info.Target == Target.CubemapArray;
            bool cubeCompatible = gd.IsAmdGcn ? isCube : (info.Width == info.Height && layers >= 6);

            if (type == ImageType.ImageType2D && cubeCompatible)
            {
                flags |= ImageCreateFlags.ImageCreateCubeCompatibleBit;
            }

            if (type == ImageType.ImageType3D)
            {
                flags |= ImageCreateFlags.ImageCreate2DArrayCompatibleBit;
            }

            var imageCreateInfo = new ImageCreateInfo()
            {
                SType         = StructureType.ImageCreateInfo,
                ImageType     = type,
                Format        = format,
                Extent        = extent,
                MipLevels     = levels,
                ArrayLayers   = layers,
                Samples       = sampleCountFlags,
                Tiling        = ImageTiling.Optimal,
                Usage         = usage,
                SharingMode   = SharingMode.Exclusive,
                InitialLayout = ImageLayout.Undefined,
                Flags         = flags
            };

            gd.Api.CreateImage(device, imageCreateInfo, null, out _image).ThrowOnError();

            if (foreignAllocation == null)
            {
                gd.Api.GetImageMemoryRequirements(device, _image, out var requirements);
                var allocation = gd.MemoryAllocator.AllocateDeviceMemory(physicalDevice, requirements, DefaultImageMemoryFlags);

                if (allocation.Memory.Handle == 0UL)
                {
                    gd.Api.DestroyImage(device, _image, null);
                    throw new Exception("Image initialization failed.");
                }

                _size = requirements.Size;

                gd.Api.BindImageMemory(device, _image, allocation.Memory, allocation.Offset).ThrowOnError();

                _allocationAuto = new Auto <MemoryAllocation>(allocation);
                _imageAuto      = new Auto <DisposableImage>(new DisposableImage(_gd.Api, device, _image), null, _allocationAuto);

                InitialTransition(ImageLayout.Undefined, ImageLayout.General);
            }
            else
            {
                _foreignAllocationAuto = foreignAllocation;
                foreignAllocation.IncrementReferenceCount();
                var allocation = foreignAllocation.GetUnsafe();

                gd.Api.BindImageMemory(device, _image, allocation.Memory, allocation.Offset).ThrowOnError();

                _imageAuto = new Auto <DisposableImage>(new DisposableImage(_gd.Api, device, _image));

                InitialTransition(ImageLayout.Preinitialized, ImageLayout.General);
            }
        }
Esempio n. 17
0
 internal static unsafe extern Result vkCreateImage(Device device, ImageCreateInfo* createInfo, AllocationCallbacks* allocator, Image* image);
Esempio n. 18
0
        private unsafe void CreateImage()
        {
            // Create a new image
            var createInfo = new ImageCreateInfo
            {
                StructureType = StructureType.ImageCreateInfo,
                ArrayLayers   = (uint)ArraySize,
                Extent        = new Extent3D((uint)Width, (uint)Height, (uint)Depth),
                MipLevels     = (uint)MipLevels,
                Samples       = SampleCountFlags.Sample1,
                Format        = NativeFormat,
                Flags         = ImageCreateFlags.None,
                Tiling        = ImageTiling.Optimal,
                InitialLayout = ImageLayout.Undefined
            };

            switch (Dimension)
            {
            case TextureDimension.Texture1D:
                createInfo.ImageType = ImageType.Image1D;
                break;

            case TextureDimension.Texture2D:
                createInfo.ImageType = ImageType.Image2D;
                break;

            case TextureDimension.Texture3D:
                createInfo.ImageType = ImageType.Image3D;
                break;

            case TextureDimension.TextureCube:
                createInfo.ImageType = ImageType.Image2D;
                createInfo.Flags    |= ImageCreateFlags.CubeCompatible;
                break;
            }

            // TODO VULKAN: Can we restrict more based on GraphicsResourceUsage?
            createInfo.Usage |= ImageUsageFlags.TransferSource | ImageUsageFlags.TransferDestination;

            if (IsRenderTarget)
            {
                createInfo.Usage |= ImageUsageFlags.ColorAttachment;
            }

            if (IsDepthStencil)
            {
                createInfo.Usage |= ImageUsageFlags.DepthStencilAttachment;
            }

            if (IsShaderResource)
            {
                createInfo.Usage |= ImageUsageFlags.Sampled; // TODO VULKAN: Input attachments
            }
            var memoryProperties = MemoryPropertyFlags.DeviceLocal;

            // Create native image
            // TODO: Multisampling, flags, usage, etc.
            NativeImage = GraphicsDevice.NativeDevice.CreateImage(ref createInfo);

            // Allocate and bind memory
            MemoryRequirements memoryRequirements;

            GraphicsDevice.NativeDevice.GetImageMemoryRequirements(NativeImage, out memoryRequirements);

            AllocateMemory(memoryProperties, memoryRequirements);

            if (NativeMemory != DeviceMemory.Null)
            {
                GraphicsDevice.NativeDevice.BindImageMemory(NativeImage, NativeMemory, 0);
            }
        }
Esempio n. 19
0
        public unsafe TextureStorage(
            VulkanGraphicsDevice gd,
            PhysicalDevice physicalDevice,
            Device device,
            TextureCreateInfo info,
            float scaleFactor,
            Auto <MemoryAllocation> foreignAllocation = null)
        {
            _gd         = gd;
            _device     = device;
            _info       = info;
            ScaleFactor = scaleFactor;

            var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format);
            var levels = (uint)info.Levels;
            var layers = (uint)info.GetLayers();
            var depth  = (uint)(info.Target == Target.Texture3D ? info.Depth : 1);

            VkFormat = format;

            var type = info.Target.Convert();

            var extent = new Extent3D((uint)info.Width, (uint)info.Height, depth);

            var sampleCountFlags = ConvertToSampleCountFlags((uint)info.Samples);

            var usage = DefaultUsageFlags;

            if (info.Format.IsDepthOrStencil())
            {
                usage |= ImageUsageFlags.ImageUsageDepthStencilAttachmentBit;
            }
            else if (info.Format.IsRtColorCompatible())
            {
                usage |= ImageUsageFlags.ImageUsageColorAttachmentBit;
            }

            if (info.Format.IsImageCompatible())
            {
                usage |= ImageUsageFlags.ImageUsageStorageBit;
            }

            var flags = ImageCreateFlags.ImageCreateMutableFormatBit;

            if (info.BlockWidth != 1 || info.BlockHeight != 1)
            {
                flags |= ImageCreateFlags.ImageCreateBlockTexelViewCompatibleBit;
            }

            bool cubeCompatible = info.Width == info.Height && layers >= 6;

            if (type == ImageType.ImageType2D && cubeCompatible)
            {
                flags |= ImageCreateFlags.ImageCreateCubeCompatibleBit;
            }

            if (type == ImageType.ImageType3D)
            {
                flags |= ImageCreateFlags.ImageCreate2DArrayCompatibleBit;
            }

            // System.Console.WriteLine("create image " + type + " " + format + " " + levels + " " + layers + " " + usage + " " + flags);

            var imageCreateInfo = new ImageCreateInfo()
            {
                SType         = StructureType.ImageCreateInfo,
                ImageType     = type,
                Format        = format,
                Extent        = extent,
                MipLevels     = levels,
                ArrayLayers   = layers,
                Samples       = sampleCountFlags,
                Tiling        = ImageTiling.Optimal,
                Usage         = usage,
                SharingMode   = SharingMode.Exclusive,
                InitialLayout = ImageLayout.Undefined,
                Flags         = flags
            };

            gd.Api.CreateImage(device, imageCreateInfo, null, out _image).ThrowOnError();

            if (foreignAllocation == null)
            {
                gd.Api.GetImageMemoryRequirements(device, _image, out var requirements);
                var allocation = gd.MemoryAllocator.AllocateDeviceMemory(physicalDevice, requirements);

                if (allocation.Memory.Handle == 0UL)
                {
                    gd.Api.DestroyImage(device, _image, null);
                    throw new Exception("Image initialization failed.");
                }

                gd.Api.BindImageMemory(device, _image, allocation.Memory, allocation.Offset).ThrowOnError();

                _allocationAuto = new Auto <MemoryAllocation>(allocation);
                _imageAuto      = new Auto <DisposableImage>(new DisposableImage(_gd.Api, device, _image), null, _allocationAuto);

                InitialTransition(ImageLayout.Undefined, ImageLayout.General);
            }
            else
            {
                var allocation = foreignAllocation.GetUnsafe();

                gd.Api.BindImageMemory(device, _image, allocation.Memory, allocation.Offset).ThrowOnError();

                _imageAuto = new Auto <DisposableImage>(new DisposableImage(_gd.Api, device, _image));

                InitialTransition(ImageLayout.Preinitialized, ImageLayout.General);
            }
        }