1 /* 2 * Copyright 2025 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef skgpu_graphite_TextureFormat_DEFINED 9 #define skgpu_graphite_TextureFormat_DEFINED 10 11 #include "include/core/SkTextureCompressionType.h" 12 13 #include <stddef.h> 14 #include <cstdint> 15 16 namespace skgpu::graphite { 17 18 /** 19 * TextureFormat encapsulates all formats that Graphite backends support for color, depth, and 20 * stencil textures. Not every TextureFormat is available on every backend or every device. 21 * 22 * TextureFormat names follow the convention of components being written in little Endian order. 23 * The channel's or groups of identically typed channel's bit depth and type follow the channel 24 * name. A numeral `n` represents an unsigned integer of bit depth `n` normalized to [0,1] while 25 * `nF` represents a floating point number having `n` bits. If a component has a different bit 26 * depth than the previous, an underscore separates them. Optional behavioral tags follow, such as 27 * hardware sRGB decoding, extended range, or compression algorithms. 28 * 29 * TextureFormat is the union of texture formats from each backend that are of interest to Skia 30 * and Graphite. As such, the non-floating point formats are restricted to just the unsigned 31 * normalized varieties (vs. signed normalized or integral textures). The exception to this is 32 * formats that include a stencil channel, which is always an unsigned integer. Floating point 33 * formats are limited to 16-bit and 32-bit; there is not enough demand yet for 64-bit doubles yet. 34 * 35 * Not all backends support all texture format enum values, and not all backends will always support 36 * a given format on the current device. Backends are responsible for mapping from TextureFormat to 37 * the actual backend format value in Caps. A TextureFormat is considered supported when such a 38 * mapping is defined. 39 * 40 * TextureFormat describes the data representation that the texture holds when copied to or from 41 * a buffer. Regardless of the data channel ordering, the GPU will automatically swizzle reads and 42 * writes to map to/from the in-shader RGBA order: 43 * - R formats sample in the shader as R001; and store only R of the out color. 44 * - A formats sample in the shader as 000A; and store only A of the out color. 45 * - RG formats sample in the shader as RG01; and store only RG of the out color. 46 * - RGB/BGR formats sample as RGB1; and store only RGB of the out color. 47 * - RGBA/BGRA/ARGB/ABGR all sample as RGBA and store RGBA. 48 * 49 * Unlike TextureFormat, SkColorType encapsulates both a data representation and semantics that 50 * introduce a possible layer of indirection when using a TextureFormat to fulfill an SkColorType. 51 * These operations may require modifying how the values are rendered or sampled, and/or performing 52 * transformations on the CPU before/after a copy. Every SkColorType has a list of TextureFormats 53 * that can be used with that type with minimal intervention. Formats are ordered from most to least 54 * compatible by: 55 * 1. Exact match: does not require any shader swizzling or CPU manipulation. 56 * 2. Lossless w/ no semantic differences: does not require shader swizzling, but does require 57 * CPU manipulation (e.g. swap RG or force opaque). 58 * 3. Lossless w/ semantic differences: requires shader swizzling, and may or may not require 59 * CPU manipulation for upload and readback. 60 * 4. Lossy or data mismatch w/o any better fit. This is to support TextureFormats that aren't 61 * representable by any SkColorType on the CPU, but requires a valid SkColorType for the 62 * SkImageInfo of the textures' SkImage or SkSurface, e.g. compressed texture formats, 63 * multiplanar formats, or 32-bit float formats that can be used entirely within the GPU without 64 * needing to interpret it as a SkColorType on the CPU. 65 * 66 * The mapping between SkColorType and TextureFormat is defined statically. When a client creates a 67 * new SkImage or SkSurface from an SkImageInfo, the TextureFormat is chosen as the first compatible 68 * format for that SkColorType that has backend support on the device. When a client wraps a 69 * BackendTexture, they also provide an SkColorType. The wrap fails if that color type's compatible 70 * format list does not include the format of the provided BackendTexture. 71 */ 72 enum class TextureFormat : uint8_t { 73 kUnsupported, 74 // Name // VK_FORMAT | wgpu::TextureFormat | MTLPixelFormat 75 // --------------//----------------------------|-------------------------|---------------------- 76 // 1 channel // | | 77 kR8, // _R8_UNORM | ::R8Unorm | R8Unorm 78 kR16, // _R16_UNORM | ::R16Unorm | R16Unorm 79 kR16F, // _R16_SFLOAT | ::R16Float | R16Float 80 kR32F, // _R32_SFLOAT | ::R32Float | R32Float 81 kA8, // - | - | A8Unorm 82 // 2 channel //----------------------------|-------------------------|---------------------- 83 kRG8, // _R8G8_UNORM | ::RG8Unorm | RG8Unorm 84 kRG16, // _R16G16_UNORM | ::RG16Unorm | RG16Unorm 85 kRG16F, // _R16G16_SFLOAT | ::RG16Float | RG16Float 86 kRG32F, // _R32G32_SFLOAT | ::RG32Float | RG32Float 87 // 3 channel //----------------------------|-------------------------|---------------------- 88 kRGB8, // _R8G8B8_UNORM | - | - 89 kBGR8, // _B8G8R8_UNORM | - | - 90 kB5_G6_R5, // _R5G6B5_UNORM_PACK16 | - | B5G6R5Unorm 91 kR5_G6_B5, // _B5G6R5_UNORM_PACK16 | - | - 92 kRGB16, // _R16G16B16_UNORM | - | - 93 kRGB16F, // _R16G16B16_SFLOAT | - | - 94 kRGB32F, // _R32G32B32_SFLOAT | - | - 95 kRGB8_sRGB, // _R8G8B8_SRGB | - | - 96 kBGR10_XR, // - | - | BGR10_XR 97 // 4 channel //----------------------------|-------------------------|---------------------- 98 kRGBA8, // _R8G8B8A8_UNORM | ::RGBA8Unorm | RGBA8Unorm 99 // _A8B8G8R8_UNORM_PACK32 | | 100 kRGBA16, // _R16G16B16A16_UNORM | ::RGBA16Unorm | RGBA16Unorm 101 kRGBA16F, // _R16G16B16A16_SFLOAT | ::RGBA16Float | RGBA16Float 102 kRGBA32F, // _R32G32B32A32_SFLOAT | ::RGBA32Float | RGBA32Float 103 kRGB10_A2, // _A2B10G10R10_UNORM_PACK32 | ::RGB10A2Unorm | RGB10A2Unorm 104 kRGBA8_sRGB, // _R8G8B8A8_SRGB | ::RGBA8UnormSrgb | RGBA8Unorm_sRGB 105 kBGRA8, // _B8G8R8A8_UNORM | ::BGRA8Unorm | BGRA8Unorm 106 kBGR10_A2, // _A2R10G10B10_UNORM_PACK32 | - | BGR10A2Unorm 107 kBGRA8_sRGB, // _B8G8R8A8_SRGB | ::BGRA8UnormSrgb | BGRA8Unorm_sRGB 108 kABGR4, // _R4G4B4A4_UNORM_PACK16 | - | ABGR4Unorm 109 kARGB4, // _B4G4R4A4_UNORM_PACK16 | - | - 110 kBGRA10x6_XR, // - | - | BGRA10_XR 111 // Compressed //----------------------------|-------------------------|---------------------- 112 kRGB8_ETC2, // _ETC2_R8G8B8_UNORM_BLOCK | ::ETC2RGB8Unorm | ETC2_RGB8 113 kRGB8_ETC2_sRGB, // _ETC2_R8G8B8_SRGB_BLOCK | ::ETC2RGB8UnormSrgb | ETC2_RGB8_sRGB 114 kRGB8_BC1, // _BC1_RGB_UNORM_BLOCK | - | - 115 kRGBA8_BC1, // _BC1_RGBA_UNORM_BLOCK | ::BC1RGBAUnorm | BC1_RGBA 116 kRGBA8_BC1_sRGB, // _BC1_RGBA_SRGB_BLOCK | ::BC1RGBAUnormSrgb | BC1_RGBA_sRGB 117 // Multi-planar //----------------------------|-------------------------|---------------------- 118 kYUV8_P2_420, // _G8_B8R8_2PLANE_420_UNORM | ::R8BG8Biplanar420Unorm | - 119 kYUV8_P3_420, // _G8_B8_R8_3PLANE_420_UNORM | - | - 120 kYUV10x6_P2_420, // _G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16 | - 121 // | ::R10X6BG10X6Biplanar420Unorm 122 kExternal, // VkExternalFormatANDROID | ::External | - 123 // Non-color //----------------------------|-------------------------|---------------------- 124 kS8, // _S8_UINT | ::Stencil8 | Stencil8 125 kD16, // _D16_UNORM | ::Depth16Unorm | Depth16Unorm 126 kD32F, // _D32_SFLOAT | ::Depth32Float | Depth32Float 127 kD24_S8, // _D24_UNORM_S8_UINT | ::Depth24PlusStencil8 | Depth24Unorm_Stencil8 128 kD32F_S8, // _D32_SFLOAT_S8_UINT | ::Depth32FloatStencil8 | Depth32Float_Stencil8 129 130 kLast = kD32F_S8 131 }; 132 static constexpr int kTextureFormatCount = static_cast<int>(TextureFormat::kLast) + 1; 133 134 const char* TextureFormatName(TextureFormat); 135 136 SkTextureCompressionType TextureFormatCompressionType(TextureFormat); 137 138 size_t TextureFormatBytesPerBlock(TextureFormat); 139 140 // The value is mask of SkColorChannelFlag values. 141 uint32_t TextureFormatChannelMask(TextureFormat); 142 143 bool TextureFormatIsDepthOrStencil(TextureFormat); 144 145 bool TextureFormatHasDepth(TextureFormat); 146 147 bool TextureFormatHasStencil(TextureFormat); 148 149 bool TextureFormatIsMultiplanar(TextureFormat); 150 151 } // namespace skgpu::graphite 152 153 #endif // skgpu_graphite_TextureFormat_DEFINED 154