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)); }
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); }
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); }
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(); } } } }
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)); }
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); }
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)); }
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); }
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; }
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) { }
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); } }
public unsafe Image CreateImage(ref ImageCreateInfo createInfo, AllocationCallbacks* allocator = null) { Image image; fixed (ImageCreateInfo* __createInfo__ = &createInfo) { vkCreateImage(this, __createInfo__, allocator, &image).CheckError(); } return image; }
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); } }
internal static unsafe extern Result vkCreateImage(Device device, ImageCreateInfo* createInfo, AllocationCallbacks* allocator, Image* image);
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 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); } }