Beispiel #1
0
        void CreateSwapChainImageViews()
        {
            var image_view_create_info = new ImageViewCreateInfo
            {
                sType = StructureType.ImageViewCreateInfo,                   // VkStructureType                sType
                pNext = IntPtr.Zero,                                         // const void                    *pNext
                flags = 0,                                                   // VkImageViewCreateFlagBits         flags
                //image = vulkan.SwapChain.Images[i].Handle,   // VkImage                        image
                viewType   = ImageViewType._2d,                              // VkImageViewType                viewType
                format     = vulkan.SwapChain.Format,                        // VkFormat                       format
                components = new ComponentMapping
                {                                                            // VkComponentMapping             components
                    r = ComponentSwizzle.Identity,                           // VkComponentSwizzle             r
                    g = ComponentSwizzle.Identity,                           // VkComponentSwizzle             g
                    b = ComponentSwizzle.Identity,                           // VkComponentSwizzle             b
                    a = ComponentSwizzle.Identity                            // VkComponentSwizzle             a
                },
                subresourceRange = new ImageSubresourceRange
                {                                                            // VkImageSubresourceRange        subresourceRange
                    aspectMask     = ImageAspectFlagBits.ColorBit,           // VkImageAspectFlagBits             aspectMask
                    baseMipLevel   = 0,                                      // uint32_t                       baseMipLevel
                    levelCount     = 1,                                      // uint32_t                       levelCount
                    baseArrayLayer = 0,                                      // uint32_t                       baseArrayLayer
                    layerCount     = 1                                       // uint32_t                       layerCount
                }
            };

            for (int i = 0; i < vulkan.SwapChain.Images.Length; ++i)
            {
                image_view_create_info.image = vulkan.SwapChain.Images[i].Handle;
                vk.CreateImageView(vulkan.Device, ref image_view_create_info, (AllocationCallbacks *)0, out vulkan.SwapChain.Images[i].View);
            }

            CanRender = true;
        }
Beispiel #2
0
        private unsafe ImageView GetDepthStencilView()
        {
            if (!IsDepthStencil)
            {
                return(ImageView.Null);
            }

            // Check that the format is supported
            //if (ComputeShaderResourceFormatFromDepthFormat(ViewFormat) == PixelFormat.None)
            //    throw new NotSupportedException("Depth stencil format [{0}] not supported".ToFormat(ViewFormat));

            // Create a Depth stencil view on this texture2D
            var createInfo = new ImageViewCreateInfo
            {
                StructureType    = StructureType.ImageViewCreateInfo,
                ViewType         = ImageViewType.Image2D,
                Format           = NativeFormat, //VulkanConvertExtensions.ConvertPixelFormat(ViewFormat),
                Image            = NativeImage,
                Components       = ComponentMapping.Identity,
                SubresourceRange = new ImageSubresourceRange(NativeImageAspect, 0, 1, 0, 1)
            };

            //if (IsDepthStencilReadOnly)
            //{
            //    if (!IsDepthStencilReadOnlySupported(GraphicsDevice))
            //        throw new NotSupportedException("Cannot instantiate ReadOnly DepthStencilBuffer. Not supported on this device.");

            //    // Create a Depth stencil view on this texture2D
            //    createInfo.SubresourceRange.AspectMask =  ? ;
            //    if (HasStencil)
            //        createInfo.Flags |= (int)AttachmentViewCreateFlags.AttachmentViewCreateReadOnlyStencilBit;
            //}

            return(GraphicsDevice.NativeDevice.CreateImageView(ref createInfo));
        }
        private void CreateImageViews()
        {
            vkSwapChainImageViews = new ImageView[vkSwapChainImages.Length];

            for (int i = 0; i < vkSwapChainImages.Length; i++)
            {
                var image = vkSwapChainImages[i];
                ImageViewCreateInfo createInfo = new ImageViewCreateInfo()
                {
                    Image      = image,
                    ViewType   = ImageViewType.View2D,
                    Format     = vkSwapChainImageFormat,
                    Components = new ComponentMapping()
                    {
                        R = ComponentSwizzle.Identity,
                        G = ComponentSwizzle.Identity,
                        B = ComponentSwizzle.Identity,
                        A = ComponentSwizzle.Identity
                    },
                    SubresourceRange = new ImageSubresourceRange()
                    {
                        AspectMask     = ImageAspectFlags.Color,
                        BaseMipLevel   = 0,
                        LevelCount     = 1,
                        BaseArrayLayer = 0,
                        LayerCount     = 1
                    }
                };

                vkSwapChainImageViews[i] = vkDevice.CreateImageView(createInfo);
            }
        }
Beispiel #4
0
        private unsafe Auto <DisposableImageView> CreateSwapchainImageView(Image swapchainImage, VkFormat format)
        {
            var componentMapping = new ComponentMapping(
                ComponentSwizzle.R,
                ComponentSwizzle.G,
                ComponentSwizzle.B,
                ComponentSwizzle.A);

            var aspectFlags = ImageAspectFlags.ImageAspectColorBit;

            var subresourceRange = new ImageSubresourceRange(aspectFlags, 0, 1, 0, 1);

            var imageCreateInfo = new ImageViewCreateInfo()
            {
                SType            = StructureType.ImageViewCreateInfo,
                Image            = swapchainImage,
                ViewType         = ImageViewType.ImageViewType2D,
                Format           = format,
                Components       = componentMapping,
                SubresourceRange = subresourceRange
            };

            _gd.Api.CreateImageView(_device, imageCreateInfo, null, out var imageView).ThrowOnError();
            return(new Auto <DisposableImageView>(new DisposableImageView(_gd.Api, _device, imageView)));
        }
Beispiel #5
0
        public void BindMemoryAndCreateView()
        {
            using (Image image = CreateImage())
            {
                PhysicalDeviceMemoryProperties deviceMemProps = PhysicalDevice.GetMemoryProperties();
                MemoryRequirements memReq = image.GetMemoryRequirements();

                using (DeviceMemory memory = Device.AllocateMemory(new MemoryAllocateInfo(
                    memReq.Size, 
                    deviceMemProps.MemoryTypes.IndexOf(memReq.MemoryTypeBits, 0))))
                {
                    image.BindMemory(memory);

                    var createInfo = new ImageViewCreateInfo
                    {
                        Format = Format.B8G8R8A8UNorm,
                        ViewType = ImageViewType.Image2D,
                        SubresourceRange = new ImageSubresourceRange
                        {
                            AspectMask = ImageAspects.Color,
                            LayerCount = 1,
                            LevelCount = 1
                        }
                    };
                    using (image.CreateView(createInfo)) { }
                    using (image.CreateView(createInfo, CustomAllocator)) { }
                }
            }
        }
Beispiel #6
0
        protected ImageView CreateImageView(Image image, Format imageFormat)
        {
            var subresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1);
            var createInfo       = new ImageViewCreateInfo(image, ImageViewType.ImageViewType2d, imageFormat, new ComponentMapping(), subresourceRange);

            return(device.CreateImageView(createInfo));
        }
Beispiel #7
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);
        }
Beispiel #8
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));
        }
Beispiel #9
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();
                                            }
                                }
                            }
        }
Beispiel #10
0
        private unsafe ImageView GetColorAttachmentView(ViewType viewType, int arrayOrDepthSlice, int mipIndex)
        {
            if (!IsRenderTarget)
            {
                return(ImageView.Null);
            }

            if (viewType == ViewType.MipBand)
            {
                throw new NotSupportedException("ViewSlice.MipBand is not supported for render targets");
            }

            int arrayOrDepthCount;
            int mipCount;

            GetViewSliceBounds(viewType, ref arrayOrDepthSlice, ref mipIndex, out arrayOrDepthCount, out mipCount);

            var createInfo = new ImageViewCreateInfo
            {
                StructureType    = StructureType.ImageViewCreateInfo,
                ViewType         = ImageViewType.Image2D,
                Format           = NativeFormat, // VulkanConvertExtensions.ConvertPixelFormat(ViewFormat),
                Image            = NativeImage,
                Components       = ComponentMapping.Identity,
                SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, (uint)arrayOrDepthSlice, 1, (uint)mipIndex, (uint)mipCount)
            };

            if (IsMultiSample)
            {
                throw new NotImplementedException();
            }

            if (this.ArraySize > 1)
            {
                if (IsMultiSample && Dimension != TextureDimension.Texture2D)
                {
                    throw new NotSupportedException("Multisample is only supported for 2D Textures");
                }

                if (Dimension == TextureDimension.Texture3D)
                {
                    throw new NotSupportedException("Texture Array is not supported for Texture3D");
                }
            }
            else
            {
                if (IsMultiSample && Dimension != TextureDimension.Texture2D)
                {
                    throw new NotSupportedException("Multisample is only supported for 2D RenderTarget Textures");
                }

                if (Dimension == TextureDimension.TextureCube)
                {
                    throw new NotSupportedException("TextureCube dimension is expecting an arraysize > 1");
                }
            }

            return(GraphicsDevice.NativeDevice.CreateImageView(ref createInfo));
        }
Beispiel #11
0
        ImageView CreateImageView(Image image, Format imageFormat)
        {
            // Image objects are not directly accessed by pipeline shaders for reading or writing
            // image data. Instead, image views representing contiguous ranges of the image
            // subresources and containing additional metadata are used for that purpose. Views must
            // be created on images of compatible types, and must represent a valid subset of image
            // subresources.

            var subresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1);
            var createInfo       = new ImageViewCreateInfo(image, ImageViewType.ImageViewType2d, imageFormat, new ComponentMapping(), subresourceRange);

            return(device.CreateImageView(createInfo));
        }
Beispiel #12
0
        private Framebuffer[] CreateFramebuffers(Image[] images, SurfaceFormatKhr surfaceFormat)
        {
            var displayViews = new ImageView[images.Length];

            for (var i = 0; i < images.Length; i++)
            {
                var viewCreateInfo = new ImageViewCreateInfo
                {
                    Image      = images[i],
                    ViewType   = ImageViewType.View2D,
                    Format     = surfaceFormat.Format,
                    Components = new ComponentMapping
                    {
                        R = ComponentSwizzle.R,
                        G = ComponentSwizzle.G,
                        B = ComponentSwizzle.B,
                        A = ComponentSwizzle.A
                    },
                    SubresourceRange = new ImageSubresourceRange
                    {
                        AspectMask = ImageAspectFlags.Color,
                        LevelCount = 1,
                        LayerCount = 1
                    }
                };

                displayViews[i] = _device.CreateImageView(viewCreateInfo);
            }

            var framebuffers = new Framebuffer [images.Length];

            for (var i = 0; i < images.Length; i++)
            {
                var frameBufferCreateInfo = new FramebufferCreateInfo
                {
                    Layers      = 1,
                    RenderPass  = _renderPass,
                    Attachments = new[] { displayViews[i] },
                    Width       = _surfaceCapabilities.CurrentExtent.Width,
                    Height      = _surfaceCapabilities.CurrentExtent.Height
                };

                framebuffers[i] = _device.CreateFramebuffer(frameBufferCreateInfo);
            }

            return(framebuffers);
        }
Beispiel #13
0
        protected ImageView CreateImageView(Image image, Format format = Format.R8G8B8A8Unorm)
        {
            var viewInfo = new ImageViewCreateInfo
            {
                Image            = image,
                ViewType         = ImageViewType.View2D,
                Format           = format,
                SubresourceRange = new ImageSubresourceRange
                {
                    AspectMask     = ImageAspectFlags.Color,
                    BaseMipLevel   = 0,
                    LevelCount     = 1,
                    BaseArrayLayer = 0,
                    LayerCount     = 1
                }
            };

            return(device.CreateImageView(viewInfo));
        }
Beispiel #14
0
        protected virtual void CreateBackBufferViews()
        {
            backBufferViews = new ImageView[backBuffers.Length];

            for (var i = 0; i < backBuffers.Length; i++)
            {
                var createInfo = new ImageViewCreateInfo
                {
                    StructureType    = StructureType.ImageViewCreateInfo,
                    ViewType         = ImageViewType.Image2D,
                    Format           = backBufferFormat,
                    Image            = backBuffers[i],
                    Components       = ComponentMapping.Identity,
                    SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1)
                };

                backBufferViews[i] = device.CreateImageView(ref createInfo);
            }
        }
        public FrameBufferAttachment(String Name, Image image, ImageViewType view2D, Format format, ImageAspectFlags color, uint levelCount, uint layercount)
        {
            this.Name = Name;
            var viewCreateInfo = new ImageViewCreateInfo
            {
                Image            = image,
                ViewType         = view2D,
                Format           = format,
                SubresourceRange = new ImageSubresourceRange
                {
                    AspectMask = color,
                    LevelCount = levelCount,
                    LayerCount = layercount
                }
            };

            VulkanRenderer.SelectedLogicalDevice.CreateImageView(this, viewCreateInfo);
            viewCreateInfo.Dispose();
        }
        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;
        }
Beispiel #17
0
        private unsafe ImageView CreateSwapchainImageView(Image swapchainImage, Format format)
        {
            var componentMapping = new ComponentMapping(
                ComponentSwizzle.Identity,
                ComponentSwizzle.Identity,
                ComponentSwizzle.Identity,
                ComponentSwizzle.Identity);

            var subresourceRange = new ImageSubresourceRange(ImageAspectFlags.ImageAspectColorBit, 0, 1, 0, 1);

            var imageCreateInfo = new ImageViewCreateInfo
            {
                SType            = StructureType.ImageViewCreateInfo,
                Image            = swapchainImage,
                ViewType         = ImageViewType.ImageViewType2D,
                Format           = format,
                Components       = componentMapping,
                SubresourceRange = subresourceRange
            };

            _instance.Api.CreateImageView(_device.InternalHandle, imageCreateInfo, null, out var imageView).ThrowOnError();
            return(imageView);
        }
Beispiel #18
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);
            }
        }
Beispiel #19
0
        protected virtual void CreateBackBufferViews()
        {
            backBufferViews = new ImageView[backBuffers.Length];

            for (var i = 0; i < backBuffers.Length; i++)
            {
                var createInfo = new ImageViewCreateInfo
                {
                    StructureType = StructureType.ImageViewCreateInfo,
                    ViewType = ImageViewType.Image2D,
                    Format = backBufferFormat,
                    Image = backBuffers[i],
                    Components = ComponentMapping.Identity,
                    SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1)
                };

                backBufferViews[i] = device.CreateImageView(ref createInfo);
            }
        }
 public FrameBufferAttachment(ImageViewCreateInfo myViewCreateInfo)
 {
     VulkanRenderer.SelectedLogicalDevice.CreateImageView(this, myViewCreateInfo);
 }
Beispiel #21
0
        public TextureView(
            VulkanGraphicsDevice gd,
            Device device,
            TextureCreateInfo info,
            TextureStorage storage,
            int firstLayer,
            int firstLevel)
        {
            _gd        = gd;
            _device    = device;
            Info       = info;
            Storage    = storage;
            FirstLayer = firstLayer;
            FirstLevel = firstLevel;

            gd.Textures.Add(this);

            var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format);
            var levels = (uint)info.Levels;
            var layers = (uint)info.GetLayers();

            VkFormat = format;

            var type = info.Target.ConvertView();

            var swizzleR = info.SwizzleR.Convert();
            var swizzleG = info.SwizzleG.Convert();
            var swizzleB = info.SwizzleB.Convert();
            var swizzleA = info.SwizzleA.Convert();

            if (info.Format == GAL.Format.R5G5B5A1Unorm ||
                info.Format == GAL.Format.R5G5B5X1Unorm ||
                info.Format == GAL.Format.R5G6B5Unorm)
            {
                var temp = swizzleR;

                swizzleR = swizzleB;
                swizzleB = temp;
            }
            else if (info.Format == GAL.Format.R4G4B4A4Unorm)
            {
                var tempR = swizzleR;
                var tempG = swizzleG;

                swizzleR = swizzleA;
                swizzleG = swizzleB;
                swizzleB = tempG;
                swizzleA = tempR;
            }

            var componentMapping = new ComponentMapping(swizzleR, swizzleG, swizzleB, swizzleA);

            var aspectFlags      = info.Format.ConvertAspectFlags(info.DepthStencilMode);
            var aspectFlagsDepth = info.Format.ConvertAspectFlags(DepthStencilMode.Depth);

            var subresourceRange      = new ImageSubresourceRange(aspectFlags, (uint)firstLevel, levels, (uint)firstLayer, layers);
            var subresourceRangeDepth = new ImageSubresourceRange(aspectFlagsDepth, (uint)firstLevel, levels, (uint)firstLayer, layers);

            unsafe Auto <DisposableImageView> CreateImageView(ComponentMapping cm, ImageSubresourceRange sr, ImageViewType viewType)
            {
                var imageCreateInfo = new ImageViewCreateInfo()
                {
                    SType            = StructureType.ImageViewCreateInfo,
                    Image            = storage.GetImageForViewCreation(),
                    ViewType         = viewType,
                    Format           = format,
                    Components       = cm,
                    SubresourceRange = sr
                };

                gd.Api.CreateImageView(device, imageCreateInfo, null, out var imageView).ThrowOnError();
                return(new Auto <DisposableImageView>(new DisposableImageView(gd.Api, device, imageView), null, storage.GetImage()));
            }

            _imageView = CreateImageView(componentMapping, subresourceRange, type);

            // Framebuffer attachments and storage images requires a identity component mapping.
            var identityComponentMapping = new ComponentMapping(
                ComponentSwizzle.R,
                ComponentSwizzle.G,
                ComponentSwizzle.B,
                ComponentSwizzle.A);

            _imageViewIdentity = CreateImageView(identityComponentMapping, subresourceRangeDepth, type);

            // Framebuffer attachments also requires 3D textures to be bound as 2D array.
            if (info.Target == Target.Texture3D)
            {
                subresourceRange = new ImageSubresourceRange(aspectFlags, (uint)firstLevel, levels, (uint)firstLayer, (uint)info.Depth);

                _imageView2dArray = CreateImageView(identityComponentMapping, subresourceRange, ImageViewType.ImageViewType2DArray);
            }

            Valid = true;
        }
Beispiel #22
0
        public bool CreateSwapChain(DrunkSpock spock,
                                    int extentX, int extentY)
        {
            PhysicalDevice phys = mLogical.Parent;
            SurfaceKhr     surf = spock.GetSurface();

            SurfaceCapabilitiesKhr surfCaps = phys.GetSurfaceCapabilitiesKhr(surf);

            SurfaceFormatKhr                [] surfFormats = phys.GetSurfaceFormatsKhr(surf);
            PresentModeKhr                  [] presModes   = phys.GetSurfacePresentModesKhr(surf);

            if (surfFormats.Length <= 0 || presModes.Length <= 0)
            {
                Misc.SafeInvoke(eErrorSpam, "Bad formats or pres modes...");
                return(false);
            }

            mSwapExtent = new Extent2D(extentX, extentY);

            int imageCount = surfCaps.MinImageCount + 1;

            if (surfCaps.MaxImageCount > 0 && imageCount > surfCaps.MaxImageCount)
            {
                imageCount = surfCaps.MaxImageCount;
            }

            SwapchainCreateInfoKhr scci = new SwapchainCreateInfoKhr(
                surf, Format.B8G8R8A8UNorm, mSwapExtent,
                imageCount, ColorSpaceKhr.SRgbNonlinear, 1,
                ImageUsages.ColorAttachment);

            scci.ImageSharingMode = SharingMode.Exclusive;

            if (presModes.Contains(PresentModeKhr.Mailbox))
            {
                scci.PresentMode = PresentModeKhr.Mailbox;
            }

            mSwapChain = mLogical.CreateSwapchainKhr(scci);
            if (mSwapChain == null)
            {
                Misc.SafeInvoke(eErrorSpam, "Create swap chain failed...");
                return(false);
            }

            VulkanCore.Image        [] chainImages = mSwapChain.GetImages();

            mChainImageViews = new ImageView[chainImages.Length];

            for (int i = 0; i < chainImages.Length; i++)
            {
                ImageSubresourceRange isr = new ImageSubresourceRange(
                    ImageAspects.Color, 0, 1, 0, 1);

                ImageViewCreateInfo ivci = new ImageViewCreateInfo(
                    mSwapChain.Format, isr);

                mChainImageViews[i] = chainImages[i].CreateView(ivci);
            }

            //descriptor pool stuff
            DescriptorPoolSize dps = new DescriptorPoolSize(
                DescriptorType.UniformBuffer, chainImages.Length);

            DescriptorPoolCreateInfo dpci = new DescriptorPoolCreateInfo();

            dpci.PoolSizes = new DescriptorPoolSize[] { dps };
            dpci.MaxSets   = chainImages.Length;

            mDPool = mLogical.CreateDescriptorPool(dpci);

            return(true);
        }
        private unsafe void CreateBackBuffers()
        {
            backbuffer.OnDestroyed();

            // Create the texture object
            var backBufferDescription = new TextureDescription
            {
                ArraySize        = 1,
                Dimension        = TextureDimension.Texture2D,
                Height           = Description.BackBufferHeight,
                Width            = Description.BackBufferWidth,
                Depth            = 1,
                Flags            = TextureFlags.RenderTarget,
                Format           = Description.BackBufferFormat,
                MipLevels        = 1,
                MultisampleCount = MultisampleCount.None,
                Usage            = GraphicsResourceUsage.Default
            };

            backbuffer.InitializeWithoutResources(backBufferDescription);

            var createInfo = new ImageViewCreateInfo
            {
                StructureType    = StructureType.ImageViewCreateInfo,
                SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1),
                Format           = backbuffer.NativeFormat,
                ViewType         = ImageViewType.Image2D
            };

            // We initialize swapchain images to PresentSource, since we swap them out while in this layout.
            backbuffer.NativeAccessMask = AccessFlags.MemoryRead;
            backbuffer.NativeLayout     = ImageLayout.PresentSource;

            var imageMemoryBarrier = new ImageMemoryBarrier
            {
                StructureType         = StructureType.ImageMemoryBarrier,
                SubresourceRange      = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1),
                OldLayout             = ImageLayout.Undefined,
                NewLayout             = ImageLayout.PresentSource,
                SourceAccessMask      = AccessFlags.None,
                DestinationAccessMask = AccessFlags.MemoryRead
            };

            var commandBuffer = GraphicsDevice.NativeCopyCommandBuffer;
            var beginInfo     = new CommandBufferBeginInfo {
                StructureType = StructureType.CommandBufferBeginInfo
            };

            commandBuffer.Begin(ref beginInfo);

            var buffers = GraphicsDevice.NativeDevice.GetSwapchainImages(swapChain);

            swapchainImages = new SwapChainImageInfo[buffers.Length];

            for (int i = 0; i < buffers.Length; i++)
            {
                // Create image views
                swapchainImages[i].NativeImage = createInfo.Image = buffers[i];
                swapchainImages[i].NativeColorAttachmentView = GraphicsDevice.NativeDevice.CreateImageView(ref createInfo);

                // Transition to default layout
                imageMemoryBarrier.Image = buffers[i];
                commandBuffer.PipelineBarrier(PipelineStageFlags.AllCommands, PipelineStageFlags.AllCommands, DependencyFlags.None, 0, null, 0, null, 1, &imageMemoryBarrier);
            }

            // Close and submit
            commandBuffer.End();

            var submitInfo = new SubmitInfo
            {
                StructureType      = StructureType.SubmitInfo,
                CommandBufferCount = 1,
                CommandBuffers     = new IntPtr(&commandBuffer),
            };

            GraphicsDevice.NativeCommandQueue.Submit(1, &submitInfo, Fence.Null);
            GraphicsDevice.NativeCommandQueue.WaitIdle();
            commandBuffer.Reset(CommandBufferResetFlags.None);

            // need to make a fence, but can immediately reset it, as it acts as a dummy
            var fenceCreateInfo = new FenceCreateInfo {
                StructureType = StructureType.FenceCreateInfo
            };

            presentFence = GraphicsDevice.NativeDevice.CreateFence(ref fenceCreateInfo);

            currentBufferIndex = GraphicsDevice.NativeDevice.AcquireNextImage(swapChain, ulong.MaxValue, SharpVulkan.Semaphore.Null, presentFence);

            fixed(Fence *fences = &presentFence)
            {
                GraphicsDevice.NativeDevice.ResetFences(1, fences);
            }

            // Apply the first swap chain image to the texture
            backbuffer.SetNativeHandles(swapchainImages[currentBufferIndex].NativeImage, swapchainImages[currentBufferIndex].NativeColorAttachmentView);
        }
        private unsafe ImageView GetDepthStencilView()
        {
            if (!IsDepthStencil)
                return ImageView.Null;

            // Check that the format is supported
            //if (ComputeShaderResourceFormatFromDepthFormat(ViewFormat) == PixelFormat.None)
            //    throw new NotSupportedException("Depth stencil format [{0}] not supported".ToFormat(ViewFormat));

            // Create a Depth stencil view on this texture2D
            var createInfo = new ImageViewCreateInfo
            {
                StructureType = StructureType.ImageViewCreateInfo,
                ViewType = ImageViewType.Image2D,
                Format = NativeFormat, //VulkanConvertExtensions.ConvertPixelFormat(ViewFormat),
                Image = NativeImage,
                Components = ComponentMapping.Identity,
                SubresourceRange = new ImageSubresourceRange(NativeImageAspect, 0, 1, 0, 1)
            };

            //if (IsDepthStencilReadOnly)
            //{
            //    if (!IsDepthStencilReadOnlySupported(GraphicsDevice))
            //        throw new NotSupportedException("Cannot instantiate ReadOnly DepthStencilBuffer. Not supported on this device.");

            //    // Create a Depth stencil view on this texture2D
            //    createInfo.SubresourceRange.AspectMask =  ? ;
            //    if (HasStencil)
            //        createInfo.Flags |= (int)AttachmentViewCreateFlags.AttachmentViewCreateReadOnlyStencilBit;
            //}

            return GraphicsDevice.NativeDevice.CreateImageView(ref createInfo);
        }
        private unsafe ImageView GetColorAttachmentView(ViewType viewType, int arrayOrDepthSlice, int mipIndex)
        {
            if (!IsRenderTarget)
                return ImageView.Null;

            if (viewType == ViewType.MipBand)
                throw new NotSupportedException("ViewSlice.MipBand is not supported for render targets");

            int arrayOrDepthCount;
            int mipCount;
            GetViewSliceBounds(viewType, ref arrayOrDepthSlice, ref mipIndex, out arrayOrDepthCount, out mipCount);

            var createInfo = new ImageViewCreateInfo
            {
                StructureType = StructureType.ImageViewCreateInfo,
                ViewType = ImageViewType.Image2D,
                Format = NativeFormat, // VulkanConvertExtensions.ConvertPixelFormat(ViewFormat),
                Image = NativeImage,
                Components = ComponentMapping.Identity,
                SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, (uint)arrayOrDepthSlice, 1, (uint)mipIndex, (uint)mipCount)
            };

            if (IsMultiSample)
                throw new NotImplementedException();

            if (this.ArraySize > 1)
            {
                if (IsMultiSample && Dimension != TextureDimension.Texture2D)
                    throw new NotSupportedException("Multisample is only supported for 2D Textures");

                if (Dimension == TextureDimension.Texture3D)
                    throw new NotSupportedException("Texture Array is not supported for Texture3D");
            }
            else
            {
                if (IsMultiSample && Dimension != TextureDimension.Texture2D)
                    throw new NotSupportedException("Multisample is only supported for 2D RenderTarget Textures");

                if (Dimension == TextureDimension.TextureCube)
                    throw new NotSupportedException("TextureCube dimension is expecting an arraysize > 1");
            }

            return GraphicsDevice.NativeDevice.CreateImageView(ref createInfo);
        }
        private unsafe ImageView GetImageView(ViewType viewType, int arrayOrDepthSlice, int mipIndex)
        {
            if (!IsShaderResource)
                return ImageView.Null;

            if (viewType == ViewType.MipBand)
                throw new NotSupportedException("ViewSlice.MipBand is not supported for render targets");

            int arrayOrDepthCount;
            int mipCount;
            GetViewSliceBounds(viewType, ref arrayOrDepthSlice, ref mipIndex, out arrayOrDepthCount, out mipCount);

            var layerCount = Dimension == TextureDimension.Texture3D ? 1 : arrayOrDepthCount;

            var createInfo = new ImageViewCreateInfo
            {
                StructureType = StructureType.ImageViewCreateInfo,
                Format = NativeFormat, //VulkanConvertExtensions.ConvertPixelFormat(ViewFormat),
                Image = NativeImage,
                Components = ComponentMapping.Identity,
                SubresourceRange = new ImageSubresourceRange(IsDepthStencil ? ImageAspectFlags.Depth : ImageAspectFlags.Color, (uint)arrayOrDepthSlice, (uint)layerCount, (uint)mipIndex, (uint)mipCount) // TODO VULKAN: Select between depth and stencil?
            };

            if (IsMultiSample)
                throw new NotImplementedException();

            if (this.ArraySize > 1)
            {
                if (IsMultiSample && Dimension != TextureDimension.Texture2D)
                    throw new NotSupportedException("Multisample is only supported for 2D Textures");

                if (Dimension == TextureDimension.Texture3D)
                    throw new NotSupportedException("Texture Array is not supported for Texture3D");

                switch (Dimension)
                {
                    case TextureDimension.Texture1D:
                        createInfo.ViewType = ImageViewType.Image1DArray;
                        break;
                    case TextureDimension.Texture2D:
                        createInfo.ViewType = ImageViewType.Image2DArray;
                        break;
                    case TextureDimension.TextureCube:
                        if (ArraySize % 6 != 0) throw new NotSupportedException("Texture cubes require an ArraySize which is a multiple of 6");

                        createInfo.ViewType = ArraySize > 6 ? ImageViewType.ImageCubeArray : ImageViewType.ImageCube;
                        break;
                }
            }
            else
            {
                if (IsMultiSample && Dimension != TextureDimension.Texture2D)
                    throw new NotSupportedException("Multisample is only supported for 2D RenderTarget Textures");

                if (Dimension == TextureDimension.TextureCube)
                    throw new NotSupportedException("TextureCube dimension is expecting an arraysize > 1");

                switch (Dimension)
                {
                    case TextureDimension.Texture1D:
                        createInfo.ViewType = ImageViewType.Image1D;
                        break;
                    case TextureDimension.Texture2D:
                        createInfo.ViewType = ImageViewType.Image2D;
                        break;
                    case TextureDimension.Texture3D:
                        createInfo.ViewType = ImageViewType.Image3D;
                        break;
                }
            }

            return GraphicsDevice.NativeDevice.CreateImageView(ref createInfo);
        }
Beispiel #27
0
        public void CreateSwapChain(PresentModeKhr presentMode, uint imageCount)
        {
            SwapchainKhr oldSwapChain = SwapChain;

            if (SwapSurface == null)
            {
                // == Create Surface for Swap Chain
                IntPtr hInstance = System.Runtime.InteropServices.Marshal.GetHINSTANCE(this.GetType().Module);

                Win32SurfaceCreateInfoKhr surfaceInfo = new Win32SurfaceCreateInfoKhr()
                {
                    Hwnd      = window.Handle,
                    Flags     = 0,
                    Hinstance = hInstance,
                };

                SurfaceKhr surface = Instance.CreateWin32SurfaceKHR(surfaceInfo, null);

                QueueInfo graphicsQueueInfo = GetQueue(QueueFlags.Graphics);
                Queue     graphicsQueue     = Device.GetQueue(graphicsQueueInfo.queueFamilyIndex, graphicsQueueInfo.queueIndex);

                SwapSurface = surface;
            }

            // == Create Swap Chain

            // TODO : this is bugged in Vulkan-Mono PresentModeKhr can not be called from Marshal.SizeOf

            /*bool presentModeSupported = false;
             * PresentModeKhr[] presentModes = Gpu.GetSurfacePresentModesKHR(SwapSurface);
             * foreach (PresentModeKhr checkMode in presentModes)
             * {
             *  if(checkMode == presentMode)
             *  {
             *      presentModeSupported = true;
             *      break;
             *  }
             * }
             * if(!presentModeSupported )
             * {
             *  throw new Exception("PresentMode :" + presentMode + " not supported by gpu.");
             * }*/

            SurfaceCapabilitiesKhr surfaceCapabilities = Gpu.GetSurfaceCapabilitiesKHR(SwapSurface);

            if (surfaceCapabilities.CurrentExtent.Width == uint.MaxValue)
            {
                BackBufferWidth  = (uint)window.Width;
                BackBufferHeight = (uint)window.Height;
            }
            else
            {
                BackBufferWidth  = surfaceCapabilities.CurrentExtent.Width;
                BackBufferHeight = surfaceCapabilities.CurrentExtent.Height;
            }

            uint reqImageCount = surfaceCapabilities.MinImageCount + imageCount;

            if (reqImageCount > 0 && reqImageCount > surfaceCapabilities.MaxImageCount)
            {
                reqImageCount = surfaceCapabilities.MaxImageCount;
            }


            SurfaceFormatKhr[] surfaceFormats = Gpu.GetSurfaceFormatsKHR(SwapSurface);
            Format             format         = surfaceFormats.Length == 1 && surfaceFormats[0].Format == Format.Undefined ?
                                                Format.B8g8r8a8Unorm : surfaceFormats[0].Format;
            SurfaceTransformFlagsKhr preTransform = (surfaceCapabilities.SupportedTransforms & SurfaceTransformFlagsKhr.Identity) == SurfaceTransformFlagsKhr.Identity ?
                                                    SurfaceTransformFlagsKhr.Identity : surfaceCapabilities.CurrentTransform;

            SwapchainCreateInfoKhr swapChainInfo = new SwapchainCreateInfoKhr
            {
                Surface         = SwapSurface,
                MinImageCount   = reqImageCount,
                ImageFormat     = format,
                ImageColorSpace = surfaceFormats[0].ColorSpace,
                ImageExtent     = new Extent2D
                {
                    Width  = BackBufferWidth,
                    Height = BackBufferHeight,
                },
                ImageUsage       = (uint)ImageUsageFlags.ColorAttachment,
                PreTransform     = preTransform,
                CompositeAlpha   = CompositeAlphaFlagsKhr.Opaque,
                ImageArrayLayers = 1,
                ImageSharingMode = SharingMode.Exclusive,
                PresentMode      = presentMode,
                // TODO : Vulkan : we cant assing a null swapChain
                //OldSwapchain = oldSwapChain != null ? oldSwapChain : null,
                Clipped = true,
            };

            if (oldSwapChain != null)
            {
                // this is a workaround as we cant assing a null one
                swapChainInfo.OldSwapchain = oldSwapChain;

                Device.DestroySwapchainKHR(oldSwapChain, null);
                oldSwapChain = null;
            }

            SwapchainKhr swapChain = Device.CreateSwapchainKHR(swapChainInfo, null);

            // ==  Create Images

            Image[] swapImages = Device.GetSwapchainImagesKHR(swapChain);

            SwapChainBuffer[] buffers = new SwapChainBuffer[swapImages.Length];
            for (uint i = 0; i < buffers.Length; i++)
            {
                ImageViewCreateInfo imageViewInfo = new ImageViewCreateInfo
                {
                    Format     = format,
                    Components = new ComponentMapping
                    {
                        R = ComponentSwizzle.R,
                        G = ComponentSwizzle.G,
                        B = ComponentSwizzle.B,
                        A = ComponentSwizzle.A,
                    },
                    SubresourceRange = new ImageSubresourceRange
                    {
                        AspectMask     = (uint)ImageAspectFlags.Color,
                        BaseMipLevel   = 1,
                        BaseArrayLayer = 0,
                        LayerCount     = 1,
                    },
                    ViewType = ImageViewType.View2D,
                    Flags    = 0,
                    Image    = swapImages[i],
                };

                ImageView view = Device.CreateImageView(imageViewInfo, null);

                buffers[i] = new SwapChainBuffer
                {
                    image = swapImages[i],
                    view  = view,
                };
            }
        }
        private unsafe void CreateBackBuffers()
        {
            // Create the texture object
            var backBufferDescription = new TextureDescription
            {
                ArraySize = 1,
                Dimension = TextureDimension.Texture2D,
                Height = Description.BackBufferHeight,
                Width = Description.BackBufferWidth,
                Depth = 1,
                Flags = TextureFlags.RenderTarget,
                Format = Description.BackBufferFormat,
                MipLevels = 1,
                MultiSampleLevel = MSAALevel.None,
                Usage = GraphicsResourceUsage.Default
            };
            backbuffer.InitializeWithoutResources(backBufferDescription);

            var createInfo = new ImageViewCreateInfo
            {
                StructureType = StructureType.ImageViewCreateInfo,
                SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1),
                Format = backbuffer.NativeFormat,
            };

            // We initialize swapchain images to PresentSource, since we swap them out while in this layout.
            backbuffer.NativeAccessMask = AccessFlags.MemoryRead;
            backbuffer.NativeLayout = ImageLayout.PresentSource;

            var imageMemoryBarrier = new ImageMemoryBarrier
            {
                StructureType = StructureType.ImageMemoryBarrier,
                SubresourceRange = new ImageSubresourceRange(ImageAspectFlags.Color, 0, 1, 0, 1),
                OldLayout = ImageLayout.Undefined,
                NewLayout = ImageLayout.PresentSource,
                SourceAccessMask = AccessFlags.None,
                DestinationAccessMask = AccessFlags.MemoryRead
            };

            var commandBuffer = GraphicsDevice.NativeCopyCommandBuffer;
            var beginInfo = new CommandBufferBeginInfo { StructureType = StructureType.CommandBufferBeginInfo };
            commandBuffer.Begin(ref beginInfo);

            var buffers = GraphicsDevice.NativeDevice.GetSwapchainImages(swapChain);
            swapchainImages = new SwapChainImageInfo[buffers.Length];

            for (int i = 0; i < buffers.Length; i++)
            {
                // Create image views
                swapchainImages[i].NativeImage = createInfo.Image = buffers[i];
                swapchainImages[i].NativeColorAttachmentView = GraphicsDevice.NativeDevice.CreateImageView(ref createInfo);

                // Transition to default layout
                imageMemoryBarrier.Image = buffers[i];
                commandBuffer.PipelineBarrier(PipelineStageFlags.AllCommands, PipelineStageFlags.AllCommands, DependencyFlags.None, 0, null, 0, null, 1, &imageMemoryBarrier);
            }

            // Close and submit
            commandBuffer.End();

            var submitInfo = new SubmitInfo
            {
                StructureType = StructureType.SubmitInfo,
                CommandBufferCount = 1,
                CommandBuffers = new IntPtr(&commandBuffer),
            };
            GraphicsDevice.NativeCommandQueue.Submit(1, &submitInfo, Fence.Null);
            GraphicsDevice.NativeCommandQueue.WaitIdle();
            commandBuffer.Reset(CommandBufferResetFlags.None);

            // Get next image
            currentBufferIndex = GraphicsDevice.NativeDevice.AcquireNextImage(swapChain, ulong.MaxValue, GraphicsDevice.GetNextPresentSemaphore(), Fence.Null);
            
            // Apply the first swap chain image to the texture
            backbuffer.SetNativeHandles(swapchainImages[currentBufferIndex].NativeImage, swapchainImages[currentBufferIndex].NativeColorAttachmentView);
        }
Beispiel #29
0
 internal static unsafe extern Result vkCreateImageView(Device device, ImageViewCreateInfo* createInfo, AllocationCallbacks* allocator, ImageView* view);
Beispiel #30
0
        private unsafe ImageView GetImageView(ViewType viewType, int arrayOrDepthSlice, int mipIndex)
        {
            if (!IsShaderResource)
            {
                return(ImageView.Null);
            }

            if (viewType == ViewType.MipBand)
            {
                throw new NotSupportedException("ViewSlice.MipBand is not supported for render targets");
            }

            int arrayOrDepthCount;
            int mipCount;

            GetViewSliceBounds(viewType, ref arrayOrDepthSlice, ref mipIndex, out arrayOrDepthCount, out mipCount);

            var layerCount = Dimension == TextureDimension.Texture3D ? 1 : arrayOrDepthCount;

            var createInfo = new ImageViewCreateInfo
            {
                StructureType    = StructureType.ImageViewCreateInfo,
                Format           = NativeFormat, //VulkanConvertExtensions.ConvertPixelFormat(ViewFormat),
                Image            = NativeImage,
                Components       = ComponentMapping.Identity,
                SubresourceRange = new ImageSubresourceRange(IsDepthStencil ? ImageAspectFlags.Depth : ImageAspectFlags.Color, (uint)arrayOrDepthSlice, (uint)layerCount, (uint)mipIndex, (uint)mipCount) // TODO VULKAN: Select between depth and stencil?
            };

            if (IsMultiSample)
            {
                throw new NotImplementedException();
            }

            if (this.ArraySize > 1)
            {
                if (IsMultiSample && Dimension != TextureDimension.Texture2D)
                {
                    throw new NotSupportedException("Multisample is only supported for 2D Textures");
                }

                if (Dimension == TextureDimension.Texture3D)
                {
                    throw new NotSupportedException("Texture Array is not supported for Texture3D");
                }

                switch (Dimension)
                {
                case TextureDimension.Texture1D:
                    createInfo.ViewType = ImageViewType.Image1DArray;
                    break;

                case TextureDimension.Texture2D:
                    createInfo.ViewType = ImageViewType.Image2DArray;
                    break;

                case TextureDimension.TextureCube:
                    createInfo.ViewType = ImageViewType.ImageCubeArray;
                    break;
                }
            }
            else
            {
                if (IsMultiSample && Dimension != TextureDimension.Texture2D)
                {
                    throw new NotSupportedException("Multisample is only supported for 2D RenderTarget Textures");
                }

                if (Dimension == TextureDimension.TextureCube)
                {
                    throw new NotSupportedException("TextureCube dimension is expecting an arraysize > 1");
                }

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

                case TextureDimension.Texture2D:
                    createInfo.ViewType = ImageViewType.Image2D;
                    break;

                case TextureDimension.Texture3D:
                    createInfo.ViewType = ImageViewType.Image3D;
                    break;

                case TextureDimension.TextureCube:
                    createInfo.ViewType = ImageViewType.ImageCube;
                    break;
                }
            }

            return(GraphicsDevice.NativeDevice.CreateImageView(ref createInfo));
        }
Beispiel #31
0
        private SwapchainKHR CreateSwapchain(out Extent2D extent, out Format swapImageFormat, out SwapchainImage[] swapImages)
        {
            QuerySwapchainSupport(this.PhysicalDevice, out var details);

            var surfaceFormat = ChooseSwapSurfaceFormat(details.Formats);
            var presentMode   = ChooseSwapPresentMode(details.PresentModes);

            extent = ChooseSwapExtent(details.Capabilities);

            var imageCount = details.Capabilities.MinImageCount + 1;

            if (details.Capabilities.MaxImageCount > 0 && imageCount > details.Capabilities.MaxImageCount)
            {
                imageCount = details.Capabilities.MaxImageCount;
            }

            var createInfo = new SwapchainCreateInfoKHR
            {
                SType            = StructureType.SwapchainCreateInfoKhr,
                Surface          = this.WindowSurface,
                MinImageCount    = imageCount,
                ImageFormat      = surfaceFormat.Format,
                ImageColorSpace  = surfaceFormat.ColorSpace,
                ImageExtent      = extent,
                ImageArrayLayers = 1,
                ImageUsage       = ImageUsageFlags.ImageUsageColorAttachmentBit
            };

            if (this.QueueIndices.GraphicsFamily != this.QueueIndices.PresentFamily)
            {
                createInfo.ImageSharingMode      = SharingMode.Concurrent;
                createInfo.QueueFamilyIndexCount = 2;

                var indices = stackalloc uint[2] {
                    this.QueueIndices.GraphicsFamily.Value, this.QueueIndices.PresentFamily.Value
                };

                createInfo.PQueueFamilyIndices = indices;
            }
            else
            {
                createInfo.ImageSharingMode = SharingMode.Exclusive;
            }

            createInfo.PreTransform   = details.Capabilities.CurrentTransform;
            createInfo.CompositeAlpha = CompositeAlphaFlagsKHR.CompositeAlphaOpaqueBitKhr;
            createInfo.PresentMode    = presentMode;
            createInfo.Clipped        = true;

            createInfo.OldSwapchain = default;

            SwapchainKHR swapchain;

            var res = this.VkSwapchain.CreateSwapchain(Device, &createInfo, null, &swapchain);

            if (res != Result.Success)
            {
                throw new VMASharp.VulkanResultException("Failed to create swapchain!", res);
            }

            uint count = 0;

            res = VkSwapchain.GetSwapchainImages(this.Device, swapchain, &count, null);

            if (res != Result.Success)
            {
                throw new VMASharp.VulkanResultException("Failed to retrieve swapchain images!", res);
            }

            var images = stackalloc Image[(int)count];

            res = VkSwapchain.GetSwapchainImages(this.Device, swapchain, &count, images);

            if (res != Result.Success)
            {
                throw new VMASharp.VulkanResultException("Failed to retrieve swapchain images!", res);
            }

            var viewCreateInfo = new ImageViewCreateInfo
            {
                SType      = StructureType.ImageViewCreateInfo,
                ViewType   = ImageViewType.ImageViewType2D,
                Format     = surfaceFormat.Format,
                Components =
                {
                    R = ComponentSwizzle.Identity,
                    G = ComponentSwizzle.Identity,
                    B = ComponentSwizzle.Identity,
                    A = ComponentSwizzle.Identity
                },
                SubresourceRange =
                {
                    AspectMask     = ImageAspectFlags.ImageAspectColorBit,
                    BaseMipLevel   =                                    0,
                    LevelCount     =                                    1,
                    BaseArrayLayer =                                    0,
                    LayerCount     = 1
                }
            };

            var arr = new SwapchainImage[count];

            for (int i = 0; i < arr.Length; ++i)
            {
                viewCreateInfo.Image = images[i];

                ImageView view = default;
                res = VkApi.CreateImageView(this.Device, &viewCreateInfo, null, &view);

                if (res != Result.Success)
                {
                    throw new VMASharp.VulkanResultException("Swapchain image view creation failed!", res);
                }

                arr[i] = new SwapchainImage {
                    Image = images[i], View = view
                };
            }

            swapImageFormat = surfaceFormat.Format;
            swapImages      = arr;

            return(swapchain);
        }
Beispiel #32
0
 public unsafe ImageView CreateImageView(ref ImageViewCreateInfo createInfo, AllocationCallbacks* allocator = null)
 {
     ImageView view;
     fixed (ImageViewCreateInfo* __createInfo__ = &createInfo)
     {
         vkCreateImageView(this, __createInfo__, allocator, &view).CheckError();
     }
     return view;
 }
Beispiel #33
0
		public void Create(CommandBuffer commandBuffer) {
			var surfaceCapabilities = PhysicalDevice.GetSurfaceCapabilitiesKHR(Surface);
			Extent2D swapChainExtend = new Extent2D {
				Width = surfaceCapabilities.CurrentExtent.Width,
				Height = surfaceCapabilities.CurrentExtent.Height
			};

			var presentModes = PhysicalDevice.GetSurfacePresentModesKHR(Surface);
			PresentModeKhr presentMode = GetBestPresentMode(presentModes);

			var desiredImages = surfaceCapabilities.MinImageCount + 1;
			if (surfaceCapabilities.MaxImageCount > 0 && desiredImages > surfaceCapabilities.MaxImageCount) {
				desiredImages = surfaceCapabilities.MaxImageCount;
			}

			var preTransform = surfaceCapabilities.CurrentTransform;
			if (surfaceCapabilities.SupportedTransforms.HasFlag(SurfaceTransformFlagsKhr.Identity)) {
				preTransform = SurfaceTransformFlagsKhr.Identity;
			}

			var oldSwapChain = Swapchain;
			var swapChainCreateInfo = new SwapchainCreateInfoKhr {
				Surface = Surface,
				MinImageCount = desiredImages,
				ImageFormat = ColorFormat,
				ImageColorSpace = ColorSpace,
				ImageExtent = swapChainExtend,
				ImageUsage = ImageUsageFlags.ColorAttachment,
				PreTransform = preTransform,
				ImageArrayLayers = 1,
				ImageSharingMode = SharingMode.Exclusive,
				QueueFamilyIndexCount = 0,
				QueueFamilyIndices = null,
				PresentMode = presentMode,
				Clipped = true,

				// Alpha on the window surface should be opaque:
				// If it was not we could create transparent regions of our window which
				// would require support from the Window compositor. You can totally do
				// that if you wanted though ;)
				CompositeAlpha = CompositeAlphaFlagsKhr.Opaque
			};
			Swapchain = Device.CreateSwapchainKHR(swapChainCreateInfo);

			if (oldSwapChain != null) {
				Device.DestroySwapchainKHR(oldSwapChain);
			}

			Images = Device.GetSwapchainImagesKHR(Swapchain).ToList();

			// Create the image views for the swap chain. They will all be single
			// layer, 2D images, with no mipmaps.
			// Check the VkImageViewCreateInfo structure to see other views you
			// can potentially create.
			for (var i = 0; i < Images.Count; i++) {
				var buffer = new SwapChainBuffer();

				var colorAttachmentView = new ImageViewCreateInfo {
					Format = ColorFormat,
					Components = new ComponentMapping {
						R = ComponentSwizzle.R,
						G = ComponentSwizzle.G,
						B = ComponentSwizzle.B,
						A = ComponentSwizzle.A
					},
					SubresourceRange = new ImageSubresourceRange {
						AspectMask = ImageAspectFlags.Color,
						BaseMipLevel = 0,
						LevelCount = 1,
						BaseArrayLayer = 0,
						LayerCount = 1
					},
					ViewType = ImageViewType.View2D
				};
				buffer.Image = Images[i];
				SetImageLayout(commandBuffer, buffer.Image, ImageAspectFlags.Color, ImageLayout.Undefined, ImageLayout.PresentSrcKhr);
				buffer.View = Device.CreateImageView(colorAttachmentView);
				Buffers.Add(buffer);
			}
		}