• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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