internal Image(Device device, VkImage image, VkFormat format) //for images that are implicitly created, eg a swapchains's images { Device = device; this.image = image; Format = format; }
public static void vkGetFormatSize(VkFormat format, out VkFormatSize pFormatSize) { switch (format) { case VkFormat.R4g4UnormPack8: pFormatSize.flags = VkFormatSizeFlag.SizePacked; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 1 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.R4g4b4a4UnormPack16: case VkFormat.B4g4r4a4UnormPack16: case VkFormat.R5g6b5UnormPack16: case VkFormat.B5g6r5UnormPack16: case VkFormat.R5g5b5a1UnormPack16: case VkFormat.B5g5r5a1UnormPack16: case VkFormat.A1r5g5b5UnormPack16: pFormatSize.flags = VkFormatSizeFlag.SizePacked; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 2 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.R8Unorm: case VkFormat.R8Snorm: case VkFormat.R8Uscaled: case VkFormat.R8Sscaled: case VkFormat.R8Uint: case VkFormat.R8Sint: case VkFormat.R8Srgb: pFormatSize.flags = 0; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 1 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.R8g8Unorm: case VkFormat.R8g8Snorm: case VkFormat.R8g8Uscaled: case VkFormat.R8g8Sscaled: case VkFormat.R8g8Uint: case VkFormat.R8g8Sint: case VkFormat.R8g8Srgb: pFormatSize.flags = 0; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 2 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.R8g8b8Unorm: case VkFormat.R8g8b8Snorm: case VkFormat.R8g8b8Uscaled: case VkFormat.R8g8b8Sscaled: case VkFormat.R8g8b8Uint: case VkFormat.R8g8b8Sint: case VkFormat.R8g8b8Srgb: case VkFormat.B8g8r8Unorm: case VkFormat.B8g8r8Snorm: case VkFormat.B8g8r8Uscaled: case VkFormat.B8g8r8Sscaled: case VkFormat.B8g8r8Uint: case VkFormat.B8g8r8Sint: case VkFormat.B8g8r8Srgb: pFormatSize.flags = 0; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 3 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.R8g8b8a8Unorm: case VkFormat.R8g8b8a8Snorm: case VkFormat.R8g8b8a8Uscaled: case VkFormat.R8g8b8a8Sscaled: case VkFormat.R8g8b8a8Uint: case VkFormat.R8g8b8a8Sint: case VkFormat.R8g8b8a8Srgb: case VkFormat.B8g8r8a8Unorm: case VkFormat.B8g8r8a8Snorm: case VkFormat.B8g8r8a8Uscaled: case VkFormat.B8g8r8a8Sscaled: case VkFormat.B8g8r8a8Uint: case VkFormat.B8g8r8a8Sint: case VkFormat.B8g8r8a8Srgb: pFormatSize.flags = 0; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 4 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.A8b8g8r8UnormPack32: case VkFormat.A8b8g8r8SnormPack32: case VkFormat.A8b8g8r8UscaledPack32: case VkFormat.A8b8g8r8SscaledPack32: case VkFormat.A8b8g8r8UintPack32: case VkFormat.A8b8g8r8SintPack32: case VkFormat.A8b8g8r8SrgbPack32: pFormatSize.flags = VkFormatSizeFlag.SizePacked; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 4 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.A2r10g10b10UnormPack32: case VkFormat.A2r10g10b10SnormPack32: case VkFormat.A2r10g10b10UscaledPack32: case VkFormat.A2r10g10b10SscaledPack32: case VkFormat.A2r10g10b10UintPack32: case VkFormat.A2r10g10b10SintPack32: case VkFormat.A2b10g10r10UnormPack32: case VkFormat.A2b10g10r10SnormPack32: case VkFormat.A2b10g10r10UscaledPack32: case VkFormat.A2b10g10r10SscaledPack32: case VkFormat.A2b10g10r10UintPack32: case VkFormat.A2b10g10r10SintPack32: pFormatSize.flags = VkFormatSizeFlag.SizePacked; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 4 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.R16Unorm: case VkFormat.R16Snorm: case VkFormat.R16Uscaled: case VkFormat.R16Sscaled: case VkFormat.R16Uint: case VkFormat.R16Sint: case VkFormat.R16Sfloat: pFormatSize.flags = 0; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 2 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.R16g16Unorm: case VkFormat.R16g16Snorm: case VkFormat.R16g16Uscaled: case VkFormat.R16g16Sscaled: case VkFormat.R16g16Uint: case VkFormat.R16g16Sint: case VkFormat.R16g16Sfloat: pFormatSize.flags = 0; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 4 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.R16g16b16Unorm: case VkFormat.R16g16b16Snorm: case VkFormat.R16g16b16Uscaled: case VkFormat.R16g16b16Sscaled: case VkFormat.R16g16b16Uint: case VkFormat.R16g16b16Sint: case VkFormat.R16g16b16Sfloat: pFormatSize.flags = 0; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 6 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.R16g16b16a16Unorm: case VkFormat.R16g16b16a16Snorm: case VkFormat.R16g16b16a16Uscaled: case VkFormat.R16g16b16a16Sscaled: case VkFormat.R16g16b16a16Uint: case VkFormat.R16g16b16a16Sint: case VkFormat.R16g16b16a16Sfloat: pFormatSize.flags = 0; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 8 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.R32Uint: case VkFormat.R32Sint: case VkFormat.R32Sfloat: pFormatSize.flags = 0; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 4 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.R32g32Uint: case VkFormat.R32g32Sint: case VkFormat.R32g32Sfloat: pFormatSize.flags = 0; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 8 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.R32g32b32Uint: case VkFormat.R32g32b32Sint: case VkFormat.R32g32b32Sfloat: pFormatSize.flags = 0; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 12 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.R32g32b32a32Uint: case VkFormat.R32g32b32a32Sint: case VkFormat.R32g32b32a32Sfloat: pFormatSize.flags = 0; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 16 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.R64Uint: case VkFormat.R64Sint: case VkFormat.R64Sfloat: pFormatSize.flags = 0; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 8 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.R64g64Uint: case VkFormat.R64g64Sint: case VkFormat.R64g64Sfloat: pFormatSize.flags = 0; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 16 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.R64g64b64Uint: case VkFormat.R64g64b64Sint: case VkFormat.R64g64b64Sfloat: pFormatSize.flags = 0; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 24 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.R64g64b64a64Uint: case VkFormat.R64g64b64a64Sint: case VkFormat.R64g64b64a64Sfloat: pFormatSize.flags = 0; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 32 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.B10g11r11UfloatPack32: case VkFormat.E5b9g9r9UfloatPack32: pFormatSize.flags = VkFormatSizeFlag.SizePacked; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 4 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.D16Unorm: pFormatSize.flags = VkFormatSizeFlag.SizeDepth; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 2 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.X8D24UnormPack32: pFormatSize.flags = VkFormatSizeFlag.SizePacked | VkFormatSizeFlag.SizeDepth; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 4 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.D32Sfloat: pFormatSize.flags = VkFormatSizeFlag.SizeDepth; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 4 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.S8Uint: pFormatSize.flags = VkFormatSizeFlag.SizeStencil; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 1 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.D16UnormS8Uint: pFormatSize.flags = VkFormatSizeFlag.SizeDepth | VkFormatSizeFlag.SizeStencil; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 3 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.D24UnormS8Uint: pFormatSize.flags = VkFormatSizeFlag.SizeDepth | VkFormatSizeFlag.SizeStencil; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 4 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.D32SfloatS8Uint: pFormatSize.flags = VkFormatSizeFlag.SizeDepth | VkFormatSizeFlag.SizeStencil; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 8 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; case VkFormat.Bc1RgbUnormBlock: case VkFormat.Bc1RgbSrgbBlock: case VkFormat.Bc1RgbaUnormBlock: case VkFormat.Bc1RgbaSrgbBlock: pFormatSize.flags = VkFormatSizeFlag.SizeCompressed; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 8 * 8; pFormatSize.blockWidth = 4; pFormatSize.blockHeight = 4; pFormatSize.blockDepth = 1; break; case VkFormat.Bc2UnormBlock: case VkFormat.Bc2SrgbBlock: case VkFormat.Bc3UnormBlock: case VkFormat.Bc3SrgbBlock: case VkFormat.Bc4UnormBlock: case VkFormat.Bc4SnormBlock: case VkFormat.Bc5UnormBlock: case VkFormat.Bc5SnormBlock: case VkFormat.Bc6hUfloatBlock: case VkFormat.Bc6hSfloatBlock: case VkFormat.Bc7UnormBlock: case VkFormat.Bc7SrgbBlock: pFormatSize.flags = VkFormatSizeFlag.SizeCompressed; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 16 * 8; pFormatSize.blockWidth = 4; pFormatSize.blockHeight = 4; pFormatSize.blockDepth = 1; break; case VkFormat.Etc2R8g8b8UnormBlock: case VkFormat.Etc2R8g8b8SrgbBlock: case VkFormat.Etc2R8g8b8a1UnormBlock: case VkFormat.Etc2R8g8b8a1SrgbBlock: pFormatSize.flags = VkFormatSizeFlag.SizeCompressed; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 8 * 8; pFormatSize.blockWidth = 4; pFormatSize.blockHeight = 4; pFormatSize.blockDepth = 1; break; case VkFormat.Etc2R8g8b8a8UnormBlock: case VkFormat.Etc2R8g8b8a8SrgbBlock: case VkFormat.EacR11UnormBlock: case VkFormat.EacR11SnormBlock: case VkFormat.EacR11g11UnormBlock: case VkFormat.EacR11g11SnormBlock: pFormatSize.flags = VkFormatSizeFlag.SizeCompressed; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 16 * 8; pFormatSize.blockWidth = 4; pFormatSize.blockHeight = 4; pFormatSize.blockDepth = 1; break; case VkFormat.Astc4x4UnormBlock: case VkFormat.Astc4x4SrgbBlock: pFormatSize.flags = VkFormatSizeFlag.SizeCompressed; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 16 * 8; pFormatSize.blockWidth = 4; pFormatSize.blockHeight = 4; pFormatSize.blockDepth = 1; break; case VkFormat.Astc5x4UnormBlock: case VkFormat.Astc5x4SrgbBlock: pFormatSize.flags = VkFormatSizeFlag.SizeCompressed; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 16 * 8; pFormatSize.blockWidth = 5; pFormatSize.blockHeight = 4; pFormatSize.blockDepth = 1; break; case VkFormat.Astc5x5UnormBlock: case VkFormat.Astc5x5SrgbBlock: pFormatSize.flags = VkFormatSizeFlag.SizeCompressed; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 16 * 8; pFormatSize.blockWidth = 5; pFormatSize.blockHeight = 5; pFormatSize.blockDepth = 1; break; case VkFormat.Astc6x5UnormBlock: case VkFormat.Astc6x5SrgbBlock: pFormatSize.flags = VkFormatSizeFlag.SizeCompressed; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 16 * 8; pFormatSize.blockWidth = 6; pFormatSize.blockHeight = 5; pFormatSize.blockDepth = 1; break; case VkFormat.Astc6x6UnormBlock: case VkFormat.Astc6x6SrgbBlock: pFormatSize.flags = VkFormatSizeFlag.SizeCompressed; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 16 * 8; pFormatSize.blockWidth = 6; pFormatSize.blockHeight = 6; pFormatSize.blockDepth = 1; break; case VkFormat.Astc8x5UnormBlock: case VkFormat.Astc8x5SrgbBlock: pFormatSize.flags = VkFormatSizeFlag.SizeCompressed; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 16 * 8; pFormatSize.blockWidth = 8; pFormatSize.blockHeight = 5; pFormatSize.blockDepth = 1; break; case VkFormat.Astc8x6UnormBlock: case VkFormat.Astc8x6SrgbBlock: pFormatSize.flags = VkFormatSizeFlag.SizeCompressed; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 16 * 8; pFormatSize.blockWidth = 8; pFormatSize.blockHeight = 6; pFormatSize.blockDepth = 1; break; case VkFormat.Astc8x8UnormBlock: case VkFormat.Astc8x8SrgbBlock: pFormatSize.flags = VkFormatSizeFlag.SizeCompressed; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 16 * 8; pFormatSize.blockWidth = 8; pFormatSize.blockHeight = 8; pFormatSize.blockDepth = 1; break; case VkFormat.Astc10x5UnormBlock: case VkFormat.Astc10x5SrgbBlock: pFormatSize.flags = VkFormatSizeFlag.SizeCompressed; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 16 * 8; pFormatSize.blockWidth = 10; pFormatSize.blockHeight = 5; pFormatSize.blockDepth = 1; break; case VkFormat.Astc10x6UnormBlock: case VkFormat.Astc10x6SrgbBlock: pFormatSize.flags = VkFormatSizeFlag.SizeCompressed; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 16 * 8; pFormatSize.blockWidth = 10; pFormatSize.blockHeight = 6; pFormatSize.blockDepth = 1; break; case VkFormat.Astc10x8UnormBlock: case VkFormat.Astc10x8SrgbBlock: pFormatSize.flags = VkFormatSizeFlag.SizeCompressed; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 16 * 8; pFormatSize.blockWidth = 10; pFormatSize.blockHeight = 8; pFormatSize.blockDepth = 1; break; case VkFormat.Astc10x10UnormBlock: case VkFormat.Astc10x10SrgbBlock: pFormatSize.flags = VkFormatSizeFlag.SizeCompressed; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 16 * 8; pFormatSize.blockWidth = 10; pFormatSize.blockHeight = 10; pFormatSize.blockDepth = 1; break; case VkFormat.Astc12x10UnormBlock: case VkFormat.Astc12x10SrgbBlock: pFormatSize.flags = VkFormatSizeFlag.SizeCompressed; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 16 * 8; pFormatSize.blockWidth = 12; pFormatSize.blockHeight = 10; pFormatSize.blockDepth = 1; break; case VkFormat.Astc12x12UnormBlock: case VkFormat.Astc12x12SrgbBlock: pFormatSize.flags = VkFormatSizeFlag.SizeCompressed; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 16 * 8; pFormatSize.blockWidth = 12; pFormatSize.blockHeight = 12; pFormatSize.blockDepth = 1; break; default: pFormatSize.flags = 0; pFormatSize.paletteSizeInBits = 0; pFormatSize.blockSizeInBits = 0 * 8; pFormatSize.blockWidth = 1; pFormatSize.blockHeight = 1; pFormatSize.blockDepth = 1; break; } }
private void InitializeFromImpl(DataBox[] dataBoxes = null) { NativeFormat = VulkanConvertExtensions.ConvertPixelFormat(ViewFormat); HasStencil = IsStencilFormat(ViewFormat); NativeImageAspect = IsDepthStencil ? VkImageAspectFlags.Depth : VkImageAspectFlags.Color; if (HasStencil) { NativeImageAspect |= VkImageAspectFlags.Stencil; } // For depth-stencil formats, automatically fall back to a supported one if (IsDepthStencil && HasStencil) { NativeFormat = GetFallbackDepthStencilFormat(GraphicsDevice, NativeFormat); } if (Usage == GraphicsResourceUsage.Staging) { if (NativeImage != VkImage.Null) { throw new InvalidOperationException(); } if (isNotOwningResources) { throw new InvalidOperationException(); } NativeAccessMask = VkAccessFlags.HostRead | VkAccessFlags.HostWrite; NativePipelineStageMask = VkPipelineStageFlags.Host; if (ParentTexture != null) { // Create only a view NativeBuffer = ParentTexture.NativeBuffer; NativeMemory = ParentTexture.NativeMemory; } else { CreateBuffer(); if (dataBoxes != null && dataBoxes.Length > 0) { throw new InvalidOperationException(); } } } else { if (NativeImage != VkImage.Null) { throw new InvalidOperationException(); } NativeLayout = IsRenderTarget ? VkImageLayout.ColorAttachmentOptimal : IsDepthStencil ? VkImageLayout.DepthStencilAttachmentOptimal : IsShaderResource ? VkImageLayout.ShaderReadOnlyOptimal : VkImageLayout.General; if (NativeLayout == VkImageLayout.TransferDstOptimal) { NativeAccessMask = VkAccessFlags.TransferRead; } if (NativeLayout == VkImageLayout.ColorAttachmentOptimal) { NativeAccessMask = VkAccessFlags.ColorAttachmentWrite; } if (NativeLayout == VkImageLayout.DepthStencilAttachmentOptimal) { NativeAccessMask = VkAccessFlags.DepthStencilAttachmentWrite; } if (NativeLayout == VkImageLayout.ShaderReadOnlyOptimal) { NativeAccessMask = VkAccessFlags.ShaderRead | VkAccessFlags.InputAttachmentRead; } NativePipelineStageMask = IsRenderTarget ? VkPipelineStageFlags.ColorAttachmentOutput : IsDepthStencil ? VkPipelineStageFlags.ColorAttachmentOutput | VkPipelineStageFlags.EarlyFragmentTests | VkPipelineStageFlags.LateFragmentTests : IsShaderResource ? VkPipelineStageFlags.VertexInput | VkPipelineStageFlags.FragmentShader : VkPipelineStageFlags.None; if (ParentTexture != null) { // Create only a view NativeImage = ParentTexture.NativeImage; NativeMemory = ParentTexture.NativeMemory; } else { if (!isNotOwningResources) { CreateImage(); InitializeImage(dataBoxes); } } if (!isNotOwningResources) { NativeColorAttachmentView = GetColorAttachmentView(ViewType, ArraySlice, MipLevel); NativeDepthStencilView = GetDepthStencilView(); NativeImageView = GetImageView(ViewType, ArraySlice, MipLevel); } } }
private void CreateSwapchain(uint width, uint height) { _currentImageIndex = 0; uint surfaceFormatCount = 0; vkGetPhysicalDeviceSurfaceFormatsKHR(_gd.PhysicalDevice, _surface, ref surfaceFormatCount, null); VkSurfaceFormatKHR[] formats = new VkSurfaceFormatKHR[surfaceFormatCount]; vkGetPhysicalDeviceSurfaceFormatsKHR(_gd.PhysicalDevice, _surface, ref surfaceFormatCount, out formats[0]); VkSurfaceFormatKHR surfaceFormat = new VkSurfaceFormatKHR(); if (formats.Length == 1 && formats[0].format == VkFormat.Undefined) { surfaceFormat = new VkSurfaceFormatKHR { colorSpace = VkColorSpaceKHR.SrgbNonlinearKHR, format = VkFormat.B8g8r8a8Unorm }; } else { foreach (VkSurfaceFormatKHR format in formats) { if (format.colorSpace == VkColorSpaceKHR.SrgbNonlinearKHR && format.format == VkFormat.B8g8r8a8Unorm) { surfaceFormat = format; break; } } if (surfaceFormat.format == VkFormat.Undefined) { surfaceFormat = formats[0]; } } uint presentModeCount = 0; vkGetPhysicalDeviceSurfacePresentModesKHR(_gd.PhysicalDevice, _surface, ref presentModeCount, null); VkPresentModeKHR[] presentModes = new VkPresentModeKHR[presentModeCount]; vkGetPhysicalDeviceSurfacePresentModesKHR(_gd.PhysicalDevice, _surface, ref presentModeCount, out presentModes[0]); VkPresentModeKHR presentMode = VkPresentModeKHR.FifoKHR; if (presentModes.Contains(VkPresentModeKHR.MailboxKHR)) { presentMode = VkPresentModeKHR.MailboxKHR; } else if (presentModes.Contains(VkPresentModeKHR.ImmediateKHR)) { presentMode = VkPresentModeKHR.ImmediateKHR; } vkGetPhysicalDeviceSurfaceCapabilitiesKHR(_gd.PhysicalDevice, _surface, out VkSurfaceCapabilitiesKHR surfaceCapabilities); uint imageCount = surfaceCapabilities.minImageCount + 1; VkSwapchainCreateInfoKHR swapchainCI = VkSwapchainCreateInfoKHR.New(); swapchainCI.surface = _surface; swapchainCI.presentMode = presentMode; swapchainCI.imageFormat = surfaceFormat.format; swapchainCI.imageColorSpace = surfaceFormat.colorSpace; swapchainCI.imageExtent = new VkExtent2D { width = (uint)width, height = (uint)height }; swapchainCI.minImageCount = imageCount; swapchainCI.imageArrayLayers = 1; swapchainCI.imageUsage = VkImageUsageFlags.ColorAttachment; FixedArray2 <uint> queueFamilyIndices = new FixedArray2 <uint>(_gd.GraphicsQueueIndex, _gd.PresentQueueIndex); if (_gd.GraphicsQueueIndex != _gd.PresentQueueIndex) { swapchainCI.imageSharingMode = VkSharingMode.Concurrent; swapchainCI.queueFamilyIndexCount = 2; swapchainCI.pQueueFamilyIndices = &queueFamilyIndices.First; } else { swapchainCI.imageSharingMode = VkSharingMode.Exclusive; swapchainCI.queueFamilyIndexCount = 0; } swapchainCI.preTransform = surfaceCapabilities.currentTransform; swapchainCI.compositeAlpha = VkCompositeAlphaFlagsKHR.OpaqueKHR; swapchainCI.clipped = true; VkSwapchainKHR oldSwapchain = _swapchain; swapchainCI.oldSwapchain = oldSwapchain; VkResult result = vkCreateSwapchainKHR(_gd.Device, ref swapchainCI, null, out _swapchain); CheckResult(result); if (oldSwapchain != VkSwapchainKHR.Null) { vkDestroySwapchainKHR(_gd.Device, oldSwapchain, null); } // Get the images uint scImageCount = 0; result = vkGetSwapchainImagesKHR(_gd.Device, _swapchain, ref scImageCount, null); CheckResult(result); if (_scImages == null) { _scImages = new VkImage[(int)scImageCount]; } result = vkGetSwapchainImagesKHR(_gd.Device, _swapchain, ref scImageCount, out _scImages[0]); CheckResult(result); _scImageFormat = surfaceFormat.format; _scExtent = swapchainCI.imageExtent; CreateDepthTexture(); CreateFramebuffers(); }
private VkSwapchainKHR CreateSwapchain() { VkSurfaceCapabilitiesKHR capabilities; vkGetPhysicalDeviceSurfaceCapabilitiesKHR(Context.PhysicalDevice, Surface, out capabilities).CheckResult(); uint count; vkGetPhysicalDeviceSurfaceFormatsKHR(Context.PhysicalDevice, Surface, &count, null); VkSurfaceFormatKHR[] formats = new VkSurfaceFormatKHR[(int)count]; fixed(VkSurfaceFormatKHR *formatsPtr = formats) vkGetPhysicalDeviceSurfaceFormatsKHR(Context.PhysicalDevice, Surface, &count, formatsPtr).CheckResult(); vkGetPhysicalDeviceSurfacePresentModesKHR(Context.PhysicalDevice, Surface, &count, null).CheckResult(); VkPresentModeKHR[] presentModes = new VkPresentModeKHR[count]; fixed(VkPresentModeKHR *presentModesPtr = presentModes) vkGetPhysicalDeviceSurfacePresentModesKHR(Context.PhysicalDevice, Surface, &count, presentModesPtr).CheckResult(); VkFormat format = formats.Length == 1 && formats[0].format == VkFormat.Undefined ? VkFormat.B8G8R8A8UNorm : formats[0].format; VkPresentModeKHR presentMode = presentModes.Contains(VkPresentModeKHR.Mailbox) ? VkPresentModeKHR.Mailbox : presentModes.Contains(VkPresentModeKHR.FifoRelaxed) ? VkPresentModeKHR.FifoRelaxed : presentModes.Contains(VkPresentModeKHR.Fifo) ? VkPresentModeKHR.Fifo : VkPresentModeKHR.Immediate; SwapChainSupportDetails swapChainSupport = QuerySwapChainSupport(Context.PhysicalDevice, Surface); VkSurfaceFormatKHR surfaceFormat = ChooseSwapSurfaceFormat(swapChainSupport.Formats); uint imageCount = swapChainSupport.Capabilities.minImageCount + 1; if (swapChainSupport.Capabilities.maxImageCount > 0 && imageCount > swapChainSupport.Capabilities.maxImageCount) { imageCount = swapChainSupport.Capabilities.maxImageCount; } SwapchainFormat = format; VkSwapchainCreateInfoKHR swapchainCI = new VkSwapchainCreateInfoKHR() { sType = VkStructureType.SwapchainCreateInfoKHR, pNext = null, surface = Surface, minImageCount = imageCount, imageFormat = format, imageColorSpace = surfaceFormat.colorSpace, imageExtent = capabilities.currentExtent, imageUsage = VkImageUsageFlags.ColorAttachment, preTransform = capabilities.currentTransform, imageArrayLayers = 1, imageSharingMode = VkSharingMode.Exclusive, queueFamilyIndexCount = 0, pQueueFamilyIndices = null, presentMode = presentMode, //oldSwapchain = SwapChain, // Setting clipped to VK_TRUE allows the implementation to discard rendering outside of the Surface area clipped = true, compositeAlpha = VkCompositeAlphaFlagsKHR.Opaque, }; VkSwapchainKHR SwapChain; vkCreateSwapchainKHR(Context.Device, &swapchainCI, null, out SwapChain).CheckResult(); return(SwapChain); }
internal static VkFormat GetFallbackDepthStencilFormat(GraphicsDevice device, VkFormat format) { if (format == VkFormat.D16UNormS8UInt || format == VkFormat.D24UNormS8UInt || format == VkFormat.D32SFloatS8UInt) { var fallbackFormats = new[] { format, VkFormat.D32SFloatS8UInt, VkFormat.D24UNormS8UInt, VkFormat.D16UNormS8UInt }; foreach (var fallbackFormat in fallbackFormats) { vkGetPhysicalDeviceFormatProperties(device.NativePhysicalDevice, fallbackFormat, out var formatProperties); if ((formatProperties.optimalTilingFeatures & VkFormatFeatureFlags.DepthStencilAttachment) != 0) { format = fallbackFormat; break; } } } return(format); }
public void CreateSwapChain() { VkPhysicalDevice PhysicalDevice = NativeDevice.NativeAdapter.handle; int width = Parameters.Width; int height = Parameters.Height; bool vsync = false; // Get available queue family properties uint queueCount; vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, null); VkQueueFamilyProperties *queueProps = stackalloc VkQueueFamilyProperties[(int)queueCount]; vkGetPhysicalDeviceQueueFamilyProperties(PhysicalDevice, &queueCount, queueProps); // Iterate over each queue to learn whether it supports presenting: // Find a queue with present support // Will be used to present the swap chain Images to the windowing system VkBool32 *supportsPresent = stackalloc VkBool32[(int)queueCount]; for (uint i = 0; i < queueCount; i++) { vkGetPhysicalDeviceSurfaceSupportKHR(PhysicalDevice, i, surface, out supportsPresent[i]); } // Search for a graphics and a present queue in the array of queue // families, try to find one that supports both uint graphicsQueueNodeIndex = uint.MaxValue; uint presentQueueNodeIndex = uint.MaxValue; for (uint i = 0; i < queueCount; i++) { if ((queueProps[i].queueFlags & VkQueueFlags.Graphics) != 0) { if (graphicsQueueNodeIndex is uint.MaxValue) { graphicsQueueNodeIndex = i; } if (supportsPresent[i] == true) { graphicsQueueNodeIndex = i; presentQueueNodeIndex = i; break; } } } if (presentQueueNodeIndex is uint.MaxValue) { // If there's no queue that supports both present and graphics // try to find a separate present queue for (uint i = 0; i < queueCount; ++i) { if (supportsPresent[i] == true) { presentQueueNodeIndex = i; break; } } } // Exit if either a graphics or a presenting queue hasn't been found if (graphicsQueueNodeIndex is uint.MaxValue || presentQueueNodeIndex is uint.MaxValue) { throw new InvalidOperationException("Could not find a graphics and/or presenting queue!"); } // TODO : Add support for separate graphics and presenting queue if (graphicsQueueNodeIndex != presentQueueNodeIndex) { throw new InvalidOperationException("Separate graphics and presenting queues are not supported yet!"); } // Get list of supported Surface formats uint formatCount; vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, surface, &formatCount, null); VkSurfaceFormatKHR *surfaceFormats = stackalloc VkSurfaceFormatKHR[(int)formatCount]; vkGetPhysicalDeviceSurfaceFormatsKHR(PhysicalDevice, surface, &formatCount, surfaceFormats); // If the Surface format list only includes one entry with VK_FORMAT_UNDEFINED, // there is no preferered format, so we assume VK_FORMAT_B8G8R8A8_UNORM if ((formatCount is 1) && (surfaceFormats[0].format is VkFormat.Undefined)) { color_format = VkFormat.B8G8R8A8UNorm; color_space = surfaceFormats[0].colorSpace; }
internal static PixelFormat VkToVdPixelFormat(VkFormat vkFormat) { switch (vkFormat) { case VkFormat.R8Unorm: return(PixelFormat.R8_UNorm); case VkFormat.R8Snorm: return(PixelFormat.R8_SNorm); case VkFormat.R8Uint: return(PixelFormat.R8_UInt); case VkFormat.R8Sint: return(PixelFormat.R8_SInt); case VkFormat.R16Unorm: return(PixelFormat.R16_UNorm); case VkFormat.R16Snorm: return(PixelFormat.R16_SNorm); case VkFormat.R16Uint: return(PixelFormat.R16_UInt); case VkFormat.R16Sint: return(PixelFormat.R16_SInt); case VkFormat.R16Sfloat: return(PixelFormat.R16_Float); case VkFormat.R32Uint: return(PixelFormat.R32_UInt); case VkFormat.R32Sint: return(PixelFormat.R32_SInt); case VkFormat.R32Sfloat: return(PixelFormat.R32_Float); case VkFormat.R8g8Unorm: return(PixelFormat.R8_G8_UNorm); case VkFormat.R8g8Snorm: return(PixelFormat.R8_G8_SNorm); case VkFormat.R8g8Uint: return(PixelFormat.R8_G8_UInt); case VkFormat.R8g8Sint: return(PixelFormat.R8_G8_SInt); case VkFormat.R16g16Unorm: return(PixelFormat.R16_G16_UNorm); case VkFormat.R16g16Snorm: return(PixelFormat.R16_G16_SNorm); case VkFormat.R16g16Uint: return(PixelFormat.R16_G16_UInt); case VkFormat.R16g16Sint: return(PixelFormat.R16_G16_SInt); case VkFormat.R16g16Sfloat: return(PixelFormat.R16_G16_Float); case VkFormat.R32g32Uint: return(PixelFormat.R32_G32_UInt); case VkFormat.R32g32Sint: return(PixelFormat.R32_G32_SInt); case VkFormat.R32g32Sfloat: return(PixelFormat.R32_G32_Float); case VkFormat.R8g8b8a8Unorm: return(PixelFormat.R8_G8_B8_A8_UNorm); case VkFormat.B8g8r8a8Unorm: return(PixelFormat.B8_G8_R8_A8_UNorm); case VkFormat.R8g8b8a8Snorm: return(PixelFormat.R8_G8_B8_A8_SNorm); case VkFormat.R8g8b8a8Uint: return(PixelFormat.R8_G8_B8_A8_UInt); case VkFormat.R8g8b8a8Sint: return(PixelFormat.R8_G8_B8_A8_SInt); case VkFormat.R16g16b16a16Unorm: return(PixelFormat.R16_G16_B16_A16_UNorm); case VkFormat.R16g16b16a16Snorm: return(PixelFormat.R16_G16_B16_A16_SNorm); case VkFormat.R16g16b16a16Uint: return(PixelFormat.R16_G16_B16_A16_UInt); case VkFormat.R16g16b16a16Sint: return(PixelFormat.R16_G16_B16_A16_SInt); case VkFormat.R16g16b16a16Sfloat: return(PixelFormat.R16_G16_B16_A16_Float); case VkFormat.R32g32b32a32Uint: return(PixelFormat.R32_G32_B32_A32_UInt); case VkFormat.R32g32b32a32Sint: return(PixelFormat.R32_G32_B32_A32_SInt); case VkFormat.R32g32b32a32Sfloat: return(PixelFormat.R32_G32_B32_A32_Float); case VkFormat.Bc1RgbUnormBlock: return(PixelFormat.BC1_Rgb_UNorm); case VkFormat.Bc1RgbaUnormBlock: return(PixelFormat.BC1_Rgba_UNorm); case VkFormat.Bc2UnormBlock: return(PixelFormat.BC2_UNorm); case VkFormat.Bc3UnormBlock: return(PixelFormat.BC3_UNorm); case VkFormat.A2b10g10r10UnormPack32: return(PixelFormat.R10_G10_B10_A2_UNorm); case VkFormat.A2b10g10r10UintPack32: return(PixelFormat.R10_G10_B10_A2_UInt); case VkFormat.B10g11r11UfloatPack32: return(PixelFormat.R11_G11_B10_Float); default: throw Illegal.Value <VkFormat>(); } }
public IReadOnlyList<VkSparseImageFormatProperties> GetSparseImageFormatProperties(VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling) { int count; Direct.GetPhysicalDeviceSparseImageFormatProperties(Handle, format, type, samples, usage, tiling, &count, (VkSparseImageFormatProperties*)0); var resultArray = new VkSparseImageFormatProperties[count]; fixed (VkSparseImageFormatProperties* pResultArray = resultArray) { Direct.GetPhysicalDeviceSparseImageFormatProperties(Handle, format, type, samples, usage, tiling, &count, pResultArray); return resultArray; } }
/// <summary> /// Starts building a new attachment for this render pass /// </summary> /// <param name="format">attachment's format</param> /// <param name="finalLayout">attachment's final image layout</param> /// <param name="samples">Sample count</param> /// <returns>attachment builder</returns> public AttachmentBuilder WithAttachment(VkFormat format, VkImageLayout finalLayout, VkSampleCountFlag samples = VkSampleCountFlag.Count1) { return(new AttachmentBuilder(this, format, finalLayout, samples)); }
internal static VkImageAspectFlags format_to_aspect_mask(VkFormat format) { throw new NotImplementedException(); }
public static int BlockSizeInBytes(this VkFormat format) { switch (format) { case VkFormat.BC1RGBUNormBlock: case VkFormat.BC1RGBSRgbBlock: case VkFormat.BC1RGBAUNormBlock: case VkFormat.BC1RGBASRgbBlock: return(8); case VkFormat.BC2UNormBlock: case VkFormat.BC2SRgbBlock: case VkFormat.BC3UNormBlock: case VkFormat.BC3SRgbBlock: return(16); case VkFormat.BC4UNormBlock: case VkFormat.BC4SNormBlock: return(8); case VkFormat.BC5UNormBlock: case VkFormat.BC5SNormBlock: case VkFormat.BC6HUFloatBlock: case VkFormat.BC6HSFloatBlock: case VkFormat.BC7UNormBlock: case VkFormat.BC7SRgbBlock: return(16); case VkFormat.ETC2R8G8B8UNormBlock: case VkFormat.ETC2R8G8B8SRgbBlock: case VkFormat.ETC2R8G8B8A1UNormBlock: case VkFormat.ETC2R8G8B8A1SRgbBlock: return(8); case VkFormat.ETC2R8G8B8A8UNormBlock: case VkFormat.ETC2R8G8B8A8SRgbBlock: return(16); case VkFormat.EACR11UNormBlock: case VkFormat.EACR11SNormBlock: return(8); case VkFormat.EACR11G11UNormBlock: case VkFormat.EACR11G11SNormBlock: return(16); case VkFormat.ASTC4x4UNormBlock: case VkFormat.ASTC4x4SRgbBlock: case VkFormat.ASTC5x4UNormBlock: case VkFormat.ASTC5x4SRgbBlock: case VkFormat.ASTC5x5UNormBlock: case VkFormat.ASTC5x5SRgbBlock: case VkFormat.ASTC6x5UNormBlock: case VkFormat.ASTC6x5SRgbBlock: case VkFormat.ASTC6x6UNormBlock: case VkFormat.ASTC6x6SRgbBlock: case VkFormat.ASTC8x5UNormBlock: case VkFormat.ASTC8x5SRgbBlock: case VkFormat.ASTC8x6UNormBlock: case VkFormat.ASTC8x6SRgbBlock: case VkFormat.ASTC8x8UNormBlock: case VkFormat.ASTC8x8SRgbBlock: case VkFormat.ASTC10x5UNormBlock: case VkFormat.ASTC10x5SRgbBlock: case VkFormat.ASTC10x6UNormBlock: case VkFormat.ASTC10x6SRgbBlock: case VkFormat.ASTC10x8UNormBlock: case VkFormat.ASTC10x8SRgbBlock: case VkFormat.ASTC10x10UNormBlock: case VkFormat.ASTC10x10SRgbBlock: case VkFormat.ASTC12x10UNormBlock: case VkFormat.ASTC12x10SRgbBlock: case VkFormat.ASTC12x12UNormBlock: case VkFormat.ASTC12x12SRgbBlock: return(16); //case VkFormat.Pvrtc12BppUNormBlock: //case VkFormat.Pvrtc14BppUNormBlock: //case VkFormat.Pvrtc22BppUNormBlock: //case VkFormat.Pvrtc24BppUNormBlock: //case VkFormat.Pvrtc12BppSRgbBlock: //case VkFormat.Pvrtc14BppSRgbBlock: //case VkFormat.Pvrtc22BppSRgbBlock: //case VkFormat.Pvrtc24BppSRgbBlock: // return 8; default: throw new ArgumentOutOfRangeException(nameof(format)); } }
public static void ConvertPixelFormat(PixelFormat inputFormat, out VkFormat format, out int pixelSize, out bool compressed) { compressed = false; // TODO VULKAN: Complete supported formats switch (inputFormat) { //case PixelFormat.A8_UNorm: // format = VkFormat.; // pixelSize = 1; // break; case PixelFormat.R8_UNorm: format = VkFormat.R8UNorm; pixelSize = 1; break; case PixelFormat.R8_SNorm: format = VkFormat.R8SNorm; pixelSize = 1; break; case PixelFormat.R8_UInt: format = VkFormat.R8UInt; pixelSize = 1; break; case PixelFormat.R8_SInt: format = VkFormat.R8SInt; pixelSize = 1; break; case PixelFormat.R8G8B8A8_UNorm: format = VkFormat.R8G8B8A8UNorm; pixelSize = 4; break; case PixelFormat.R8G8B8A8_UInt: format = VkFormat.R8G8B8A8UInt; pixelSize = 4; break; case PixelFormat.R8G8B8A8_SInt: format = VkFormat.R8G8B8A8SInt; pixelSize = 4; break; case PixelFormat.B8G8R8A8_UNorm: format = VkFormat.B8G8R8A8UNorm; pixelSize = 4; break; case PixelFormat.R8G8B8A8_UNorm_SRgb: format = VkFormat.R8G8B8A8SRgb; pixelSize = 4; break; case PixelFormat.B8G8R8A8_UNorm_SRgb: format = VkFormat.B8G8R8A8SRgb; pixelSize = 4; break; case PixelFormat.R16_Float: format = VkFormat.R16SFloat; pixelSize = 2; break; case PixelFormat.R16_UNorm: format = VkFormat.R16UNorm; pixelSize = 2; break; case PixelFormat.R16_UInt: format = VkFormat.R16UInt; pixelSize = 2; break; case PixelFormat.R16_SInt: format = VkFormat.R16SInt; pixelSize = 2; break; case PixelFormat.R16G16_Float: format = VkFormat.R16G16SFloat; pixelSize = 4; break; case PixelFormat.R16G16_SNorm: format = VkFormat.R16G16SNorm; pixelSize = 4; break; case PixelFormat.R16G16_UNorm: format = VkFormat.R16G16UNorm; pixelSize = 4; break; case PixelFormat.R16G16_SInt: format = VkFormat.R16G16SNorm; pixelSize = 4; break; case PixelFormat.R16G16_UInt: format = VkFormat.R16G16UNorm; pixelSize = 4; break; case PixelFormat.R16G16B16A16_Float: format = VkFormat.R16G16B16A16SFloat; pixelSize = 8; break; case PixelFormat.R16G16B16A16_UNorm: format = VkFormat.R16G16B16A16UNorm; pixelSize = 8; break; case PixelFormat.R16G16B16A16_SNorm: format = VkFormat.R16G16B16A16SNorm; pixelSize = 8; break; case PixelFormat.R16G16B16A16_UInt: format = VkFormat.R16G16B16A16UInt; pixelSize = 8; break; case PixelFormat.R16G16B16A16_SInt: format = VkFormat.R16G16B16A16SInt; pixelSize = 8; break; case PixelFormat.R32_UInt: format = VkFormat.R32UInt; pixelSize = 4; break; case PixelFormat.R32_Float: format = VkFormat.R32SFloat; pixelSize = 4; break; case PixelFormat.R32G32_Float: format = VkFormat.R32G32SFloat; pixelSize = 8; break; case PixelFormat.R32G32_UInt: format = VkFormat.R32G32UInt; pixelSize = 8; break; case PixelFormat.R32G32_SInt: format = VkFormat.R32G32SInt; pixelSize = 8; break; case PixelFormat.R32G32B32_Float: format = VkFormat.R32G32B32SFloat; pixelSize = 12; break; case PixelFormat.R32G32B32_SInt: format = VkFormat.R32G32B32SInt; pixelSize = 12; break; case PixelFormat.R32G32B32_UInt: format = VkFormat.R32G32B32UInt; pixelSize = 12; break; case PixelFormat.R32G32B32A32_Float: format = VkFormat.R32G32B32A32SFloat; pixelSize = 16; break; case PixelFormat.R32G32B32A32_SInt: format = VkFormat.R32G32B32A32SInt; pixelSize = 16; break; case PixelFormat.R32G32B32A32_UInt: format = VkFormat.R32G32B32A32UInt; pixelSize = 16; break; case PixelFormat.D16_UNorm: format = VkFormat.D16UNorm; pixelSize = 2; break; case PixelFormat.D24_UNorm_S8_UInt: format = VkFormat.D24UNormS8UInt; pixelSize = 4; break; // TODO: Temporary depth format (need to decide relation between RenderTarget1D and Texture) case PixelFormat.D32_Float: format = VkFormat.D32SFloat; pixelSize = 4; break; case PixelFormat.ETC1: case PixelFormat.ETC2_RGB: // ETC1 upper compatible format = VkFormat.ETC2R8G8B8UNormBlock; compressed = true; pixelSize = 1; // 4bpp break; case PixelFormat.ETC2_RGB_SRgb: format = VkFormat.ETC2R8G8B8SRgbBlock; compressed = true; pixelSize = 1; break; case PixelFormat.ETC2_RGB_A1: format = VkFormat.ETC2R8G8B8A1UNormBlock; compressed = true; pixelSize = 1; // 4bpp break; case PixelFormat.ETC2_RGBA: // ETC2 + EAC format = VkFormat.ETC2R8G8B8A8UNormBlock; compressed = true; pixelSize = 2; // 8bpp break; case PixelFormat.ETC2_RGBA_SRgb: // ETC2 + EAC format = VkFormat.ETC2R8G8B8A8SRgbBlock; compressed = true; pixelSize = 2; // 8bpp break; case PixelFormat.EAC_R11_Unsigned: format = VkFormat.EACR11UNormBlock; compressed = true; pixelSize = 1; // 4bpp break; case PixelFormat.EAC_R11_Signed: format = VkFormat.EACR11SNormBlock; compressed = true; pixelSize = 1; // 4bpp break; case PixelFormat.EAC_RG11_Unsigned: format = VkFormat.EACR11G11UNormBlock; compressed = true; pixelSize = 2; // 8bpp break; case PixelFormat.EAC_RG11_Signed: format = VkFormat.EACR11G11SNormBlock; compressed = true; pixelSize = 2; // 8bpp break; case PixelFormat.BC1_UNorm: format = VkFormat.BC1RGBAUNormBlock; //format = VkFormat.RAD_TEXTURE_FORMAT_DXT1_RGBA; compressed = true; pixelSize = 1; // 4bpp break; case PixelFormat.BC1_UNorm_SRgb: format = VkFormat.BC1RGBASRgbBlock; //format = VkFormat.RAD_TEXTURE_FORMAT_DXT1_RGBA_SRgb; compressed = true; pixelSize = 1; // 4bpp break; case PixelFormat.BC2_UNorm: format = VkFormat.BC2UNormBlock; compressed = true; pixelSize = 2; // 8bpp break; case PixelFormat.BC2_UNorm_SRgb: format = VkFormat.BC2SRgbBlock; compressed = true; pixelSize = 2; // 8bpp break; case PixelFormat.BC3_UNorm: format = VkFormat.BC3UNormBlock; compressed = true; pixelSize = 2; // 8bpp break; case PixelFormat.BC3_UNorm_SRgb: format = VkFormat.BC3SRgbBlock; compressed = true; pixelSize = 2; // 8bpp break; case PixelFormat.BC4_SNorm: format = VkFormat.BC4SNormBlock; compressed = true; pixelSize = 1; // 4bpp break; case PixelFormat.BC4_UNorm: format = VkFormat.BC4UNormBlock; compressed = true; pixelSize = 1; // 4bpp break; case PixelFormat.BC5_SNorm: format = VkFormat.BC5SNormBlock; compressed = true; pixelSize = 2; // 8bpp break; case PixelFormat.BC5_UNorm: format = VkFormat.BC5UNormBlock; compressed = true; pixelSize = 2; // 8bpp break; case PixelFormat.BC6H_Sf16: format = VkFormat.BC6HSFloatBlock; compressed = true; pixelSize = 2; // 8bpp break; case PixelFormat.BC6H_Uf16: format = VkFormat.BC6HUFloatBlock; compressed = true; pixelSize = 2; // 8bpp break; case PixelFormat.BC7_UNorm: format = VkFormat.BC7UNormBlock; compressed = true; pixelSize = 2; // 8bpp break; case PixelFormat.BC7_UNorm_SRgb: format = VkFormat.BC7SRgbBlock; compressed = true; pixelSize = 2; // 8bpp break; default: throw new InvalidOperationException("Unsupported texture format: " + inputFormat); } }
private void createSwapChain() { SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice); VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats); VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes); VkExtent2D extent = chooseSwapExtent(swapChainSupport.capabilities); int imageCount = swapChainSupport.capabilities.minImageCount + 1; if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount) { imageCount = swapChainSupport.capabilities.maxImageCount; } VkSwapchainCreateInfoKHR createInfo = new VkSwapchainCreateInfoKHR(); createInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; createInfo.surface = surface; createInfo.minImageCount = imageCount; createInfo.imageFormat = surfaceFormat.format; createInfo.imageColorSpace = surfaceFormat.colorSpace; createInfo.imageExtent = extent; createInfo.imageArrayLayers = 1; createInfo.imageUsage = VkImageUsageFlags.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; QueueFamilyIndices indices = findQueueFamilies(physicalDevice); var queueFamilyIndices = new List <int>() { indices.graphicsFamily, indices.presentFamily }; if (indices.graphicsFamily != indices.presentFamily) { createInfo.imageSharingMode = VkSharingMode.VK_SHARING_MODE_CONCURRENT; createInfo.queueFamilyIndexCount = queueFamilyIndices.Count; createInfo.pQueueFamilyIndices = queueFamilyIndices.ToArray(); } else { createInfo.imageSharingMode = VkSharingMode.VK_SHARING_MODE_EXCLUSIVE; } createInfo.preTransform = (VkSurfaceTransformFlagBitsKHR)swapChainSupport.capabilities.currentTransform; createInfo.compositeAlpha = VkCompositeAlphaFlagBitsKHR.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; createInfo.presentMode = presentMode; createInfo.clipped = VkBool32.VK_TRUE; createInfo.oldSwapchain = null; VkResult result = Vulkan.vkCreateSwapchainKHR(device, createInfo, null, out swapChain); if (result != VkResult.VK_SUCCESS) { throw Program.Throw("failed to create swap chain!", result); } swapChainImages = new VkImage[imageCount]; Vulkan.vkGetSwapchainImagesKHR(device, swapChain, ref imageCount, swapChainImages); swapChainImageFormat = surfaceFormat.format; swapChainExtent = extent; }
public IReadOnlyList <VkSparseImageFormatProperties> GetSparseImageFormatProperties(VkFormat format, VkImageType type, VkSampleCount samples, VkImageUsageFlags usage, VkImageTiling tiling) { int count; Direct.GetPhysicalDeviceSparseImageFormatProperties(Handle, format, type, samples, usage, tiling, &count, (VkSparseImageFormatProperties *)0); var resultArray = new VkSparseImageFormatProperties[count]; fixed(VkSparseImageFormatProperties *pResultArray = resultArray) { Direct.GetPhysicalDeviceSparseImageFormatProperties(Handle, format, type, samples, usage, tiling, &count, pResultArray); return(resultArray); } }
/// <summary> /// Tries to find a display mode that has the same size as the current <see cref="OutputDescription"/> associated with this instance /// of the specified format. /// </summary> /// <param name="format">The format to match with.</param> /// <returns>A matched <see cref="DisplayMode"/> or null if nothing is found.</returns> private DisplayMode TryFindMatchingDisplayMode(VkFormat format) { return(null); }
/// <summary> /// VkVertexInputAttributeDescription - Structure specifying vertex input attribute description. /// </summary> /// <param name="location">location is the shader binding location number for this attribute.</param> /// <param name="binding">binding is the binding number which this attribute takes its data /// from</param> /// <param name="format">format is the size and type of the vertex attribute data.</param> /// <param name="offset">offset is a byte offset of this attribute relative to the start of /// an element in the vertex input binding.</param> public VkVertexInputAttributeDescription(UInt32 location, UInt32 binding, VkFormat format, UInt32 offset) { this.location = location; this.binding = binding; this.format = format; this.offset = offset; }
void loadTexture(string fileName, VkFormat format, bool forceLinearTiling) { KtxFile tex2D; using (var fs = File.OpenRead(fileName)) { tex2D = KtxFile.Load(fs, false); } VkFormatProperties formatProperties; texture.width = tex2D.Header.PixelWidth; texture.height = tex2D.Header.PixelHeight; texture.mipLevels = tex2D.Header.NumberOfMipmapLevels; // Get Device properites for the requested texture format vkGetPhysicalDeviceFormatProperties(PhysicalDevice, format, &formatProperties); // Only use linear tiling if requested (and supported by the Device) // Support for linear tiling is mostly limited, so prefer to use // optimal tiling instead // On most implementations linear tiling will only support a very // limited amount of formats and features (mip maps, cubemaps, arrays, etc.) uint useStaging = 1; // Only use linear tiling if forced if (forceLinearTiling) { // Don't use linear if format is not supported for (linear) shader sampling useStaging = ((formatProperties.linearTilingFeatures & VkFormatFeatureFlags.SampledImage) != VkFormatFeatureFlags.SampledImage) ? 1u : 0u; } VkMemoryAllocateInfo memAllocInfo = Initializers.memoryAllocateInfo(); VkMemoryRequirements memReqs = new VkMemoryRequirements(); if (useStaging == 1) { // Create a host-visible staging buffer that contains the raw image data VkBuffer stagingBuffer; VkDeviceMemory stagingMemory; VkBufferCreateInfo bufferCreateInfo = Initializers.bufferCreateInfo(); bufferCreateInfo.size = tex2D.GetTotalSize(); // This buffer is used as a transfer source for the buffer copy bufferCreateInfo.usage = VkBufferUsageFlags.TransferSrc; bufferCreateInfo.sharingMode = VkSharingMode.Exclusive; Util.CheckResult(vkCreateBuffer(Device, &bufferCreateInfo, null, &stagingBuffer)); // Get memory requirements for the staging buffer (alignment, memory type bits) vkGetBufferMemoryRequirements(Device, stagingBuffer, &memReqs); memAllocInfo.allocationSize = memReqs.size; // Get memory type index for a host visible buffer memAllocInfo.memoryTypeIndex = VulkanDevice.GetMemoryType(memReqs.memoryTypeBits, VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent); Util.CheckResult(vkAllocateMemory(Device, &memAllocInfo, null, &stagingMemory)); Util.CheckResult(vkBindBufferMemory(Device, stagingBuffer, stagingMemory, 0)); // Copy texture data into staging buffer byte *data; Util.CheckResult(vkMapMemory(Device, stagingMemory, 0, memReqs.size, 0, (void **)&data)); byte[] allData = tex2D.GetAllTextureData(); fixed(byte *tex2DDataPtr = &allData[0]) { Unsafe.CopyBlock(data, tex2DDataPtr, (uint)allData.Length); } vkUnmapMemory(Device, stagingMemory); // Setup buffer copy regions for each mip level NativeList <VkBufferImageCopy> bufferCopyRegions = new NativeList <VkBufferImageCopy>(); uint offset = 0; for (uint i = 0; i < texture.mipLevels; i++) { VkBufferImageCopy bufferCopyRegion = new VkBufferImageCopy(); bufferCopyRegion.imageSubresource.aspectMask = VkImageAspectFlags.Color; bufferCopyRegion.imageSubresource.mipLevel = i; bufferCopyRegion.imageSubresource.baseArrayLayer = 0; bufferCopyRegion.imageSubresource.layerCount = 1; bufferCopyRegion.imageExtent.width = tex2D.Faces[0].Mipmaps[i].Width; bufferCopyRegion.imageExtent.height = tex2D.Faces[0].Mipmaps[i].Height; bufferCopyRegion.imageExtent.depth = 1; bufferCopyRegion.bufferOffset = offset; bufferCopyRegions.Add(bufferCopyRegion); offset += tex2D.Faces[0].Mipmaps[i].SizeInBytes; } // Create optimal tiled target image VkImageCreateInfo imageCreateInfo = Initializers.imageCreateInfo(); imageCreateInfo.imageType = VkImageType._2d; imageCreateInfo.format = format; imageCreateInfo.mipLevels = texture.mipLevels; imageCreateInfo.arrayLayers = 1; imageCreateInfo.samples = VkSampleCountFlags._1; imageCreateInfo.tiling = VkImageTiling.Optimal; imageCreateInfo.sharingMode = VkSharingMode.Exclusive; // Set initial layout of the image to undefined imageCreateInfo.initialLayout = VkImageLayout.Undefined; imageCreateInfo.extent = new VkExtent3D { width = texture.width, height = texture.height, depth = 1 }; imageCreateInfo.usage = VkImageUsageFlags.TransferDst | VkImageUsageFlags.Sampled; Util.CheckResult(vkCreateImage(Device, &imageCreateInfo, null, out texture.image)); vkGetImageMemoryRequirements(Device, texture.image, &memReqs); memAllocInfo.allocationSize = memReqs.size; memAllocInfo.memoryTypeIndex = VulkanDevice.GetMemoryType(memReqs.memoryTypeBits, VkMemoryPropertyFlags.DeviceLocal); Util.CheckResult(vkAllocateMemory(Device, &memAllocInfo, null, out texture.DeviceMemory)); Util.CheckResult(vkBindImageMemory(Device, texture.image, texture.DeviceMemory, 0)); VkCommandBuffer copyCmd = base.createCommandBuffer(VkCommandBufferLevel.Primary, true); // Image barrier for optimal image // The sub resource range describes the regions of the image we will be transition VkImageSubresourceRange subresourceRange = new VkImageSubresourceRange(); // Image only contains color data subresourceRange.aspectMask = VkImageAspectFlags.Color; // Start at first mip level subresourceRange.baseMipLevel = 0; // We will transition on all mip levels subresourceRange.levelCount = texture.mipLevels; // The 2D texture only has one layer subresourceRange.layerCount = 1; // Optimal image will be used as destination for the copy, so we must transfer from our // initial undefined image layout to the transfer destination layout setImageLayout( copyCmd, texture.image, VkImageAspectFlags.Color, VkImageLayout.Undefined, VkImageLayout.TransferDstOptimal, subresourceRange); // Copy mip levels from staging buffer vkCmdCopyBufferToImage( copyCmd, stagingBuffer, texture.image, VkImageLayout.TransferDstOptimal, bufferCopyRegions.Count, bufferCopyRegions.Data); // Change texture image layout to shader read after all mip levels have been copied texture.imageLayout = VkImageLayout.ShaderReadOnlyOptimal; setImageLayout( copyCmd, texture.image, VkImageAspectFlags.Color, VkImageLayout.TransferDstOptimal, texture.imageLayout, subresourceRange); flushCommandBuffer(copyCmd, Queue, true); // Clean up staging resources vkFreeMemory(Device, stagingMemory, null); vkDestroyBuffer(Device, stagingBuffer, null); } else { throw new NotImplementedException(); /* * // Prefer using optimal tiling, as linear tiling * // may support only a small set of features * // depending on implementation (e.g. no mip maps, only one layer, etc.) * * VkImage mappableImage; * VkDeviceMemory mappableMemory; * * // Load mip map level 0 to linear tiling image * VkImageCreateInfo imageCreateInfo = Initializers.imageCreateInfo(); * imageCreateInfo.imageType = VkImageType._2d; * imageCreateInfo.format = format; * imageCreateInfo.mipLevels = 1; * imageCreateInfo.arrayLayers = 1; * imageCreateInfo.samples = VkSampleCountFlags._1; * imageCreateInfo.tiling = VkImageTiling.Linear; * imageCreateInfo.usage = VkImageUsageFlags.Sampled; * imageCreateInfo.sharingMode = VkSharingMode.Exclusive; * imageCreateInfo.initialLayout = VkImageLayout.Preinitialized; * imageCreateInfo.extent = new VkExtent3D { width = texture.width, height = texture.height, depth = 1 }; * Util.CheckResult(vkCreateImage(Device, &imageCreateInfo, null, &mappableImage)); * * // Get memory requirements for this image * // like size and alignment * vkGetImageMemoryRequirements(Device, mappableImage, &memReqs); * // Set memory allocation size to required memory size * memAllocInfo.allocationSize = memReqs.size; * * // Get memory type that can be mapped to host memory * memAllocInfo.memoryTypeIndex = VulkanDevice.GetMemoryType(memReqs.memoryTypeBits, VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent); * * // Allocate host memory * Util.CheckResult(vkAllocateMemory(Device, &memAllocInfo, null, &mappableMemory)); * * // Bind allocated image for use * Util.CheckResult(vkBindImageMemory(Device, mappableImage, mappableMemory, 0)); * * // Get sub resource layout * // Mip map count, array layer, etc. * VkImageSubresource subRes = new VkImageSubresource(); * subRes.aspectMask = VkImageAspectFlags.Color; * * VkSubresourceLayout subResLayout; * void* data; * * // Get sub resources layout * // Includes row pitch, size offsets, etc. * vkGetImageSubresourceLayout(Device, mappableImage, &subRes, &subResLayout); * * // Map image memory * Util.CheckResult(vkMapMemory(Device, mappableMemory, 0, memReqs.size, 0, &data)); * * // Copy image data into memory * memcpy(data, tex2D[subRes.mipLevel].data(), tex2D[subRes.mipLevel].size()); * * vkUnmapMemory(Device, mappableMemory); * * // Linear tiled images don't need to be staged * // and can be directly used as textures * texture.image = mappableImage; * texture.DeviceMemory = mappableMemory; * texture.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; * * VkCommandBuffer copyCmd = VulkanExampleBase::createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); * * // Setup image memory barrier transfer image to shader read layout * * // The sub resource range describes the regions of the image we will be transition * VkImageSubresourceRange subresourceRange = { }; * // Image only contains color data * subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; * // Start at first mip level * subresourceRange.baseMipLevel = 0; * // Only one mip level, most implementations won't support more for linear tiled images * subresourceRange.levelCount = 1; * // The 2D texture only has one layer * subresourceRange.layerCount = 1; * * setImageLayout( * copyCmd, * texture.image, * VK_IMAGE_ASPECT_COLOR_BIT, * VK_IMAGE_LAYOUT_PREINITIALIZED, * texture.imageLayout, * subresourceRange); * * VulkanExampleBase::flushCommandBuffer(copyCmd, queue, true); */ } // Create sampler // In Vulkan textures are accessed by samplers // This separates all the sampling information from the // texture data // This means you could have multiple sampler objects // for the same texture with different settings // Similar to the samplers available with OpenGL 3.3 VkSamplerCreateInfo sampler = Initializers.samplerCreateInfo(); sampler.magFilter = VkFilter.Linear; sampler.minFilter = VkFilter.Linear; sampler.mipmapMode = VkSamplerMipmapMode.Linear; sampler.addressModeU = VkSamplerAddressMode.Repeat; sampler.addressModeV = VkSamplerAddressMode.Repeat; sampler.addressModeW = VkSamplerAddressMode.Repeat; sampler.mipLodBias = 0.0f; sampler.compareOp = VkCompareOp.Never; sampler.minLod = 0.0f; // Set max level-of-detail to mip level count of the texture sampler.maxLod = (useStaging == 1) ? (float)texture.mipLevels : 0.0f; // Enable anisotropic filtering // This feature is optional, so we must check if it's supported on the Device if (VulkanDevice.Features.samplerAnisotropy == 1) { // Use max. level of anisotropy for this example sampler.maxAnisotropy = VulkanDevice.Properties.limits.maxSamplerAnisotropy; sampler.anisotropyEnable = True; } else { // The Device does not support anisotropic filtering sampler.maxAnisotropy = 1.0f; sampler.anisotropyEnable = False; } sampler.borderColor = VkBorderColor.FloatOpaqueWhite; Util.CheckResult(vkCreateSampler(Device, ref sampler, null, out texture.sampler)); // Create image view // Textures are not directly accessed by the shaders and // are abstracted by image views containing additional // information and sub resource ranges VkImageViewCreateInfo view = Initializers.imageViewCreateInfo(); view.viewType = VkImageViewType._2d; view.format = format; view.components = new VkComponentMapping { r = VkComponentSwizzle.R, g = VkComponentSwizzle.G, b = VkComponentSwizzle.B, a = VkComponentSwizzle.A }; // The subresource range describes the set of mip levels (and array layers) that can be accessed through this image view // It's possible to create multiple image views for a single image referring to different (and/or overlapping) ranges of the image view.subresourceRange.aspectMask = VkImageAspectFlags.Color; view.subresourceRange.baseMipLevel = 0; view.subresourceRange.baseArrayLayer = 0; view.subresourceRange.layerCount = 1; // Linear tiling usually won't support mip maps // Only set mip map count if optimal tiling is used view.subresourceRange.levelCount = (useStaging == 1) ? texture.mipLevels : 1; // The view will be based on the texture's image view.image = texture.image; Util.CheckResult(vkCreateImageView(Device, &view, null, out texture.view)); }
/// <summary> /// create host visible linear image without command from path /// </summary> public static Image Load(Device dev, string path, VkImageUsageFlags usage = VkImageUsageFlags.Sampled, bool reserveSpaceForMipmaps = true, VkFormat format = VkFormat.Undefined, VkMemoryPropertyFlags memoryProps = VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent, VkImageTiling tiling = VkImageTiling.Linear, VkImageType imageType = VkImageType.Image2D) { if (format == VkFormat.Undefined) { format = DefaultTextureFormat; } using (StbImage stbi = new StbImage(path)) { uint mipLevels = reserveSpaceForMipmaps ? ComputeMipLevels(stbi.Width, stbi.Height) : 1; Image img = new Image(dev, format, usage, memoryProps, (uint)stbi.Width, (uint)stbi.Height, imageType, VkSampleCountFlags.SampleCount1, tiling, mipLevels); img.Map(); stbi.CoptyTo(img.MappedData); img.Unmap(); return(img); } }